package xcmg.device.service.sale;

import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import xcmg.device.dao.entity.DataDictionaryDO;
import xcmg.device.dao.entity.PriMaterialsDO;
import xcmg.device.dao.entity.PubMaterialsDO;
import xcmg.device.dao.entity.company.CompanyDealerDO;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.entity.company.CompanySupplierDO;
import xcmg.device.dao.entity.delivery.DeliveryNoteDO;
import xcmg.device.dao.entity.delivery.DeliveryNoteDetailDO;
import xcmg.device.dao.entity.marketing.MarketingActivityDO;
import xcmg.device.dao.entity.purchase.PurchaseRequestDO;
import xcmg.device.dao.entity.purchase.PurchaseRequestDetailDO;
import xcmg.device.dao.entity.sale.SaleIntentionDO;
import xcmg.device.dao.entity.sale.SaleIntentionDetailDO;
import xcmg.device.dao.entity.sale.SaleIntentionExportDO;
import xcmg.device.dao.mapper.CompanyDealerMapper;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.dao.mapper.CompanySupplierMapper;
import xcmg.device.dao.mapper.DataDictionaryMapper;
import xcmg.device.dao.mapper.MarketingActivityMapper;
import xcmg.device.dao.mapper.MaterialLocationRelationMapper;
import xcmg.device.dao.mapper.PriMaterialsMapper;
import xcmg.device.dao.mapper.PubMaterialsMapper;
import xcmg.device.dao.mapper.PurchaseRequestDetailMapper;
import xcmg.device.dao.mapper.PurchaseRequestMapper;
import xcmg.device.dao.mapper.SaleIntentionDetailMapper;
import xcmg.device.dao.mapper.SaleIntentionMapper;
import xcmg.device.dao.mapper.account.ArapDetailMapper;
import xcmg.device.dao.mapper.account.ArapMapper;
import xcmg.device.dao.mapper.agent.ServiceBasicDataAgentMapper;
import xcmg.device.dao.mapper.delivery.DeliveryNoteDetailMapper;
import xcmg.device.dao.mapper.delivery.DeliveryNoteMapper;
import xcmg.device.dao.mapper.salesReturn.ReturnApplyDetailMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryDetailMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseInventoryMapper;
import xcmg.device.infra.BeanUtil;
import xcmg.device.infra.ConstantInfo;
import xcmg.device.infra.DateUtil;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExcelUtil;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.FileUtil;
import xcmg.device.infra.JsonUtil;
import xcmg.device.infra.enums.BillDesc;
import xcmg.device.infra.enums.DeliveryStatus;
import xcmg.device.infra.enums.ForwardBarcodeLableEnum;
import xcmg.device.infra.enums.SaleStatus;
import xcmg.device.service.GenDocumentService;
import xcmg.device.service.basic.MaterialsService;
import xcmg.device.service.company.CompanyDealerService;
import xcmg.device.service.company.CompanyInfoService;
import xcmg.device.service.delivery.DeliveryNoteService;
import xcmg.device.service.marketing.MarketingActivityService;
import xcmg.device.service.purchase.PurchaseRequestService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.basic.MaterialLocationRelationVO;
import xcmg.device.service.vo.basic.MaterialsVO;
import xcmg.device.service.vo.delivery.DeliveryNoteAddVO;
import xcmg.device.service.vo.delivery.DeliveryNoteDetailVO;
import xcmg.device.service.vo.delivery.DeliveryNoteVO;
import xcmg.device.service.vo.marketing.MarketingActivityPriceVO;
import xcmg.device.service.vo.purchase.PurchaseRequestDetailVO;
import xcmg.device.service.vo.purchase.PurchaseRequestVO;
import xcmg.device.service.vo.sale.InformVO;
import xcmg.device.service.vo.sale.SaleAddVO;
import xcmg.device.service.vo.sale.SaleIntentionDetailVO;
import xcmg.device.service.vo.sale.SaleIntentionVO;
import xcmg.device.service.vo.warehouse.app.EnableAndOccupyVO;
import xcmg.device.service.warehouse.CommonService;
import xcmg.device.service.warehouse.WarehouseInventoryService;
import xcmg.device.util.CompanyUtil;
import xcmg.device.util.DecimalUtil;
import yb.ecp.fast.dto.ProfileDTO;
import yb.ecp.fast.dto.UserDetailDTO;
import yb.ecp.fast.feign.AuthClient;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.PageHelperPlus;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static org.apache.commons.lang.math.NumberUtils.isNumber;

@Service
@Slf4j
public class SaleIntentionService
{

    @Autowired
    private SaleIntentionMapper saleIntentionMapper;
    @Autowired
    private SaleIntentionDetailMapper saleIntentionDetailMapper;
    @Autowired
    private FastGenClient fastGenClient;
    @Autowired
    private GenDocumentService genDocumentService;
    @Autowired
    private DataDictionaryMapper dataDictionaryMapper;
    @Autowired
    private AuthClient authClient;
    @Value("${spring.file.download.path}")
    private String filePath;
    private String templateExcelFileName = "SaleInten.xls";
    @Autowired
    private HttpServletResponse response;
    @Autowired
    private MaterialsService materialsService;

    @Autowired
    private DataSourceTransactionManager transactionManager;
    @Autowired
    private MarketingActivityMapper marketingActivityMapper;
    @Autowired
    private CompanyInfoService companyInfoService;
    @Autowired
    private CompanyDealerMapper companyDealerMapper;
    @Autowired
    private CompanyInfoMapper companyInfoMapper;
    @Autowired
    private PurchaseRequestMapper purchaseRequestMapper;
    @Autowired
    private DeliveryNoteDetailMapper deliveryNoteDetailMapper;
    @Autowired
    private SaleIntentionDeleteReasonService saleIntentionDeleteReasonService;
    @Autowired
    private WarehouseInventoryService warehouseInventoryService;

    @Autowired
    private PriMaterialsMapper priMaterialsMapper;

    @Autowired
    private PurchaseRequestService purchaseRequestService;

    @Autowired
    private PurchaseRequestDetailMapper purchaseRequestDetailMapper;

    @Autowired
    private MaterialLocationRelationMapper materialLocationRelationMapper;

    @Autowired
    private MarketingActivityService marketingActivityService;

    @Autowired
    private DeliveryNoteMapper deliveryNoteMapper;

    @Autowired
    private ReturnApplyDetailMapper returnApplyDetailMapper;

    @Autowired
    private DeliveryNoteService deliveryNoteService;

    @Autowired
    private ArapMapper arapMapper;

    @Autowired
    private ArapDetailMapper arapDetailMapper;

    @Autowired
    private WarehouseDeliveryDetailMapper warehouseDeliveryDetailMapper;

    @Autowired
    private WarehouseInventoryMapper warehouseInventoryMapper;

    @Autowired
    private CompanyDealerService companyDealerService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private PubMaterialsMapper pubMaterialsMapper;

    @Autowired
    private CompanySupplierMapper companySupplierMapper;

    @Autowired
    private ServiceBasicDataAgentMapper serviceBasicDataAgentMapper;

    private static final String LACK_TEMPLATE_NAME = "lack_report_update_template.xls";

    @Value("${ns.saleIntention.restUrl:1}")
    private String saleIntentionUrl;

    @Value("${ns.auth.tokenId:1}")
    private String tokenId;

    @Value("${ns.auth.tokenSecret:1}")
    private String tokenSecret;

    @Value("${ns.auth.consumerKey:1}")
    private String consumerKey;

    @Value("${ns.auth.consumerSecret:1}")
    private String consumerSecret;

    @Value("${ns.auth.realm:1}")
    private String realm;

    public PageCommonVO list(SearchCommonVO<SaleIntentionVO> condition) throws Exception {
        SaleIntentionVO filters = condition.getFilters();
        filters.setBillNosList(xcmg.device.infra.StringUtil.getStrSplitList(filters.getBillNos()));
        filters.setMaterialsList(xcmg.device.infra.StringUtil.getStrSplitList(filters.getMaterialsNo()));
        String purchaseNames = filters.getPurchaseNames();
        if(!StringUtils.isEmpty(purchaseNames)){
            List<String> purchaseNamesList = companyDealerService.listFullNamesByShortName(filters.getSupplierOrgId(),purchaseNames);
            if (CollectionUtils.isEmpty(purchaseNamesList)) {
                PageCommonVO result = new PageCommonVO();
                result.setPageInfo(new PageInfo(Collections.EMPTY_LIST));
                result.setPageInfoList(Collections.EMPTY_LIST);
                return result;
            }else{
                filters.setPurchaseNamesList(purchaseNamesList);
            }
        }

        List<SaleIntentionDO> doList=null;
        List<SaleIntentionVO> voList = new ArrayList<>();
        PageCommonVO<SaleIntentionVO> result = new PageCommonVO<>();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize(), "create_date desc");
        doList = saleIntentionMapper.list(filters);

        //查询创建人部门
        Map<String,ProfileDTO> profileDTOMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(doList)){
            List<String> userIds = doList.stream().map(SaleIntentionDO::getCreatorId).distinct().collect(Collectors.toList());
            ActionResult<List<ProfileDTO>>  profileResult = authClient.listByIds(userIds.toArray(new String[userIds.size()]));
            if(ErrorCode.Success.getCode() != profileResult.getCode()) {
                throw new Exception(profileResult.getMessage());
            }
            List<ProfileDTO> profileList = profileResult.getValue();
            if (CollectionUtils.isNotEmpty(profileList)){
                profileDTOMap = profileList.stream().collect(Collectors.toMap(ProfileDTO::getUserId,Function.identity(),(k1,k2)->k2));
            }
        }

        for (SaleIntentionDO entity : doList)
        {
            SaleIntentionVO model = new SaleIntentionVO();
            BeanUtils.copyProperties(entity, model);
            takeDecimals(model);
            if (profileDTOMap.containsKey(model.getCreatorId())){
                model.setDeptName(profileDTOMap.get(model.getCreatorId()).getDeptName());
            }

            voList.add(model);
        }
        result.setPageInfo(new PageInfo(doList));
        result.setPageInfoList(voList);
        return result;
    }

    public PageCommonVO listByUser(SearchCommonVO<SaleIntentionVO> condition, String userId) throws Exception {
        ActionResult<UserDetailDTO> userActionResult = authClient.getUserDetail(userId);
        if (ErrorCode.Success.getCode() != userActionResult.getCode()) {
            throw new Exception(userActionResult.getMessage());
        }
        UserDetailDTO userDetail = userActionResult.getValue();
        String deptCode = null;
        if (userDetail != null) {
            deptCode = userDetail.getDeptCode();
        }
        if (deptCode == null) {
            return new PageCommonVO();
        }
        condition.getFilters().setDeptCode(deptCode);
        condition.getFilters().setBillNosList(xcmg.device.infra.StringUtil.getStrSplitList(condition.getFilters().getBillNos()));
        condition.getFilters().setMaterialsList(xcmg.device.infra.StringUtil.getStrSplitList(condition.getFilters().getMaterialsNo()));
        List<String> purchaseNamesList = companyDealerService.listFullNamesByShortName(condition.getFilters().getSupplierOrgId(), condition.getFilters().getPurchaseNames());
        if (CollectionUtils.isNotEmpty(purchaseNamesList)) {
            condition.getFilters().setPurchaseNamesList(purchaseNamesList);
        }

        List<SaleIntentionDO> doList = null;
        List<SaleIntentionVO> voList = new ArrayList<>();
        PageCommonVO<SaleIntentionVO> result = new PageCommonVO<>();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize(), "create_date desc");
        doList = saleIntentionMapper.list(condition.getFilters());
        for (SaleIntentionDO entity : doList) {
            SaleIntentionVO model = new SaleIntentionVO();
            BeanUtils.copyProperties(entity, model);
            takeDecimals(model);

            voList.add(model);
        }
        result.setPageInfo(new PageInfo(doList));
        result.setPageInfoList(voList);
        return result;
    }

    private ActionResult<String> getResult(ErrorCode errorCode, String value) {
        return new ActionResult(errorCode.getCode(),errorCode.getDesc(), value);
    }


    public ActionResult addSaleOrder4Tj(SaleAddVO model) throws Exception{
        String supplierOrgId = model.getHeaderInfo().getSupplierOrgId();
        if(StringUtils.isEmpty(supplierOrgId)){
            return getResult(ErrorCode.OrgError, "公司信息不能为空");
        }
        //这里的SupplierOrgId和PurchaseOrgId都是sapCode，属性名一开始定义好没改。是供应商与客户的上下游关系
        CompanyInfoDO companyInfoDO=companyInfoMapper.itemBySap(model.getHeaderInfo().getSupplierOrgId());
        if(companyInfoDO==null){
            return getResult(ErrorCode.OrgError, "未查询到公司信息");
        }
        String supplierOrgName = model.getHeaderInfo().getSupplierOrgName();
        //如果没有传supplierOrgName则根据supplierOrgId从conpamnyInfo中获取
        if(StringUtils.isEmpty(supplierOrgName)){
            supplierOrgName = companyInfoDO.getCompanyName();
            if(StringUtils.isEmpty(supplierOrgName)){
                return getResult(ErrorCode.OrgError, "公司信息不能为空");
            }
            model.getHeaderInfo().setSupplierOrgName(supplierOrgName);
        }
        model.getHeaderInfo().setSupplierOrgId(companyInfoDO.getOrgId());
        if(StringUtils.isEmpty(model.getHeaderInfo().getPurchaseOrgId())){
            return getResult(ErrorCode.CustomerError, "客户公司信息不能未空");
        }
        CompanyDealerDO companyDealerDO=companyDealerMapper.itemByDealerCode(model.getHeaderInfo().getSupplierOrgId(),model.getHeaderInfo().getPurchaseOrgId());
        if(companyDealerDO==null){
            return getResult(ErrorCode.DealerError, "未查询到公司客户信息");
        }
        model.getHeaderInfo().setPurchaseOrgId(companyDealerDO.getDealerOrgId());
        model.getHeaderInfo().setPurchaseOrgName(companyDealerDO.getCompanyName());

        model.getHeaderInfo().setCreatorId(model.getHeaderInfo().getSupplierOrgId());
        if(model.getHeaderInfo().getCreateName()==null){
            model.getHeaderInfo().setCreateName(model.getHeaderInfo().getCreateName());
        }
        model.getHeaderInfo().setCreateType(2);
        if(StringUtils.isEmpty(model.getHeaderInfo().getDeliverTypeId())||
                StringUtils.isEmpty(model.getHeaderInfo().getDeliverTypeName())){
            return getResult(ErrorCode.DeliveryError, "请参照字典值填写发运方式ID");
        }
        if(StringUtils.isEmpty(model.getHeaderInfo().getSettleTypeId())||
                StringUtils.isEmpty(model.getHeaderInfo().getSettleTypeName())){
            return getResult(ErrorCode.SettleError, "请参照字典值填写结算方式ID");
        }
        if(StringUtils.isEmpty(model.getHeaderInfo().getReceiverName())){
            return getResult(ErrorCode.ReceiverError, "请填写收货人姓名");
        }
        if(StringUtils.isEmpty(model.getHeaderInfo().getReceiverPhone())){
            return getResult(ErrorCode.ReceiverError, "请填写收货人电话");
        }
        for (SaleIntentionDetailVO detailVO:model.getMaterialList()) {
            PriMaterialsDO priMaterialsDO=priMaterialsMapper.itemByNo(detailVO.getMaterialsNo(),model.getHeaderInfo().getSupplierOrgId());
            if(priMaterialsDO==null){
                return getResult(ErrorCode.Failure,"零件"+detailVO.getMaterialsNo()+"在企业内不存在不存在");
            }
            detailVO.setMaterialsDes(priMaterialsDO.getMaterialsDes());
            detailVO.setRequestDeliveryDate(new Date());
            detailVO.setAmountAfterAdjust(detailVO.getQty());
            detailVO.setApplyTotalPrice(detailVO.getPrice().multiply(detailVO.getQty()));
            detailVO.setUnit(priMaterialsDO.getUnit());
            if(StringUtils.isEmpty(detailVO.getMaterialsNo())){
                return getResult(ErrorCode.MaterialsNoIsNull, "零件编号存在为空的情况");
            }
        }
        LogHelper.debug("塔机备件销售外部接口保存详情内容为>>"+ JsonUtil.objectToString(model));
        return getResult(this.add(model), model.getHeaderInfo().getSaleNo());
    }

    public ActionResult addSaleOrder(SaleAddVO model) throws Exception{
        String supplierOrgId = model.getHeaderInfo().getSupplierOrgId();
        if(StringUtils.isEmpty(supplierOrgId)){
            return getResult(ErrorCode.OrgError, "公司信息不能为空");
        }
        //这里的SupplierOrgId和PurchaseOrgId都是sapCode，属性名一开始定义好没改。是供应商与客户的上下游关系
        CompanyInfoDO companyInfoDO=companyInfoMapper.itemBySap(model.getHeaderInfo().getSupplierOrgId());
        if(companyInfoDO==null){
            return getResult(ErrorCode.OrgError, "未查询到公司信息");
        }
        String supplierOrgName = model.getHeaderInfo().getSupplierOrgName();
        //如果没有传supplierOrgName则根据supplierOrgId从conpamnyInfo中获取
        if(StringUtils.isEmpty(supplierOrgName)){
            supplierOrgName = companyInfoDO.getCompanyName();
            if(StringUtils.isEmpty(supplierOrgName)){
                return getResult(ErrorCode.OrgError, "公司信息不能为空");
            }
            model.getHeaderInfo().setSupplierOrgName(supplierOrgName);
         }
        model.getHeaderInfo().setSupplierOrgId(companyInfoDO.getOrgId());
        if(StringUtils.isEmpty(model.getHeaderInfo().getPurchaseOrgId())){
            return getResult(ErrorCode.CustomerError, "客户公司信息不能未空");
        }
        CompanyDealerDO companyDealerDO=companyDealerMapper.itemByDealerCode(model.getHeaderInfo().getSupplierOrgId(),model.getHeaderInfo().getPurchaseOrgId());
        if(companyDealerDO==null){
            return getResult(ErrorCode.DealerError, "未查询到公司客户信息");
        }
        model.getHeaderInfo().setPurchaseOrgId(companyDealerDO.getDealerOrgId());
        model.getHeaderInfo().setPurchaseOrgName(companyDealerDO.getCompanyName());

        model.getHeaderInfo().setCreatorId(model.getHeaderInfo().getSupplierOrgId());
        if(model.getHeaderInfo().getCreateName()==null){
            model.getHeaderInfo().setCreateName(model.getHeaderInfo().getCreateName());
        }
        model.getHeaderInfo().setCreateType(2);
        if(StringUtils.isEmpty(model.getHeaderInfo().getDeliverTypeId())||
                StringUtils.isEmpty(model.getHeaderInfo().getDeliverTypeName())){
            return getResult(ErrorCode.DeliveryError, "请参照字典值填写发运方式ID");
        }
        if(StringUtils.isEmpty(model.getHeaderInfo().getSettleTypeId())||
                StringUtils.isEmpty(model.getHeaderInfo().getSettleTypeName())){
            return getResult(ErrorCode.SettleError, "请参照字典值填写结算方式ID");
        }
        if(StringUtils.isEmpty(model.getHeaderInfo().getReceiverName())){
            return getResult(ErrorCode.ReceiverError, "请填写收货人姓名");
        }
        if(StringUtils.isEmpty(model.getHeaderInfo().getReceiverPhone())){
            return getResult(ErrorCode.ReceiverError, "请填写收货人电话");
        }
        for (SaleIntentionDetailVO detailVO:model.getMaterialList()) {
            PriMaterialsDO priMaterialsDO=priMaterialsMapper.itemByNo(detailVO.getMaterialsNo(),model.getHeaderInfo().getSupplierOrgId());
            if(priMaterialsDO==null){
                return getResult(ErrorCode.Failure,"零件"+detailVO.getMaterialsNo()+"在企业内不存在不存在");
            }
            detailVO.setMaterialsDes(priMaterialsDO.getMaterialsDes());
            detailVO.setRequestDeliveryDate(new Date());
            detailVO.setAmountAfterAdjust(detailVO.getQty());
            detailVO.setApplyTotalPrice(detailVO.getPrice());
            detailVO.setUnit(priMaterialsDO.getUnit());
            if(StringUtils.isEmpty(detailVO.getMaterialsNo())){
                return getResult(ErrorCode.MaterialsNoIsNull, "零件编号存在为空的情况");
            }
        }
        return getResult(this.add(model), model.getHeaderInfo().getSaleNo());
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode add(SaleAddVO model) throws Exception
    {
        model.setRet(ErrorCode.Failure);

        SaleIntentionVO headerInfo = model.getHeaderInfo();
        //自动创建的单据才检查
        if (headerInfo.getCreateType().equals(0)) {
            PurchaseRequestDO requestDO = purchaseRequestMapper.itemByBillNo(headerInfo.getPurchaseNo());
            if (requestDO != null && requestDO.getIsSale() != null && !requestDO.getIsSale().equals(0)) {
                throw new Exception("当前采购订单已生成销售意向，不能重复生成！");
            }
        }
        SaleIntentionDO entity = new SaleIntentionDO();
        BeanUtils.copyProperties(headerInfo, entity);
        if(!StringUtil.isNullOrEmpty(headerInfo.getPurchaseLevelId())){
            DataDictionaryDO dataDictionaryDO = dataDictionaryMapper.itemByCode("CGJB", headerInfo.getPurchaseLevelId());
            if (dataDictionaryDO != null)
            {
                entity.setPurchaseLevelName(dataDictionaryDO.getName());
            }
        }

        ActionResult<String> dataDictionaryDOId = fastGenClient.textGuid();
        if (dataDictionaryDOId == null || dataDictionaryDOId.getCode() != 0)
        {
            return ErrorCode.Failure;
        }
        //内部主键
        entity.setId(dataDictionaryDOId.getValue());
        //销售订单
        entity.setSaleNo(genDocumentService.getDocumentNo(BillDesc.SaleNo));
        headerInfo.setId(entity.getId());
        headerInfo.setSaleNo(entity.getSaleNo());
        //小数转换整数
        rounding(entity);
        entity.setTotalDiscountPrice(new BigDecimal("0"));
        entity.setTotalSettlementPrice(new BigDecimal("0"));
        List<SaleIntentionDetailDO> detailDOList = new ArrayList<>();
        for (SaleIntentionDetailVO detailVO : model.getMaterialList())
        {
            SaleIntentionDetailDO detailDO = new SaleIntentionDetailDO();
            BeanUtils.copyProperties(detailVO, detailDO);
            ActionResult<String> detailDOId = fastGenClient.textGuid();
            if (detailDOId == null || detailDOId.getCode() != 0)
            {
                return ErrorCode.Failure;
            }
            detailDO.setId(detailDOId.getValue());
            detailDO.setSaleIntentionId(entity.getId());
            detailDO.setSaleNo(entity.getSaleNo());
            getDetailDO(model, detailDO);

            if(detailDO.getUnitPriceAfterAdjust() == null){
                detailDO.setUnitPriceAfterAdjust(BigDecimal.ZERO);
                detailDO.setTotalPriceAfterAdjust(BigDecimal.ZERO);
            }

            if(detailDO.getUnitPriceAfterAdjust() == null || detailDO.getUnitPriceAfterAdjust().compareTo(BigDecimal.ZERO) == 0){
                entity.setIsSynPrice(1);
            }

            if(!StringUtil.isNullOrEmpty(detailDO.getPriceSchemeId())){
                MarketingActivityDO marketingActivityDO=marketingActivityMapper.item(detailDO.getPriceSchemeId());
                if(marketingActivityDO==null && !StringUtil.isNullOrEmpty(detailDO.getPriceSchemeName())){
                    marketingActivityDO=marketingActivityMapper.findByName(entity.getSupplierOrgId(),detailDO.getPriceSchemeName());
                }
                if(marketingActivityDO==null){
                    model.setRet(ErrorCode.AcivityNotFound);
                     throw new Exception("价格策略不存在");
                }
                if(marketingActivityDO.getState().equals(0)){
                    model.setRet(ErrorCode.AcivityDisabled);
                    throw new Exception("价格策略未启用");
                }
            }

            saleIntentionDetailMapper.insert(detailDO);

            detailDOList.add(detailDO);

            entity.setTotalSettlementPrice(entity.getTotalSettlementPrice().add(detailDO.getApplyTotalPrice()));

            entity.setTotalDiscountPrice(entity.getTotalDiscountPrice().add(detailDO.getTotalPriceAfterAdjust()));


        }
        if(entity.getPurchaseLevelId()==null || !"1".equals(entity.getPurchaseLevelId())){
            //判断客户额度是否足够
            CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(entity.getSupplierOrgId(), entity.getPurchaseOrgId());
            if(dealerDO == null){
                throw new Exception("未找到客户记录");
            }
            if(dealerDO.getEnableLimit() == 1){
                BigDecimal price = BigDecimal.ZERO;
                if(entity.getTotalDiscountPrice() != null){
                    price = entity.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                }
                BigDecimal totalPrice = dealerDO.getUsedLimit().add(price);
                if(totalPrice.compareTo(dealerDO.getTotalLimit()) > 0){
                    throw new Exception("客户额度已超额");
                }else{
                    dealerDO.setUsedLimit(totalPrice);
                    companyDealerMapper.update(dealerDO);
                    entity.setIsLimit(1);
                }
            }
        }

        saleIntentionMapper.insert(entity);

        if(entity.getCreateType().equals(1))
        {
            //手动创建的单据，不需要更改采购单状态
            return  ErrorCode.Success;
        }

        PurchaseRequestDO purchaseRequestDO = new PurchaseRequestDO();
        purchaseRequestDO.setBillNo(entity.getPurchaseNo());
        if("0".equals(entity.getStatus()))
        {
            //已保存
            purchaseRequestDO.setIsSale(1);
        }
        else
        {
            //已提交
            purchaseRequestDO.setIsSale(2);
        }
        purchaseRequestService.updateBySaleBill(purchaseRequestDO);
        return ErrorCode.Success;
    }

    @Transactional(rollbackFor = Exception.class)
    public synchronized String balance(SaleAddVO model) throws Exception
    {
        model.setRet(ErrorCode.Failure);
        SaleIntentionDO entity = new SaleIntentionDO();
        BeanUtils.copyProperties(model.getHeaderInfo(), entity);
        if(!StringUtil.isNullOrEmpty(model.getHeaderInfo().getPurchaseLevelId())){
            DataDictionaryDO dataDictionaryDO = dataDictionaryMapper.itemByCode("CGJB", model.getHeaderInfo().getPurchaseLevelId());
            if (dataDictionaryDO != null)
            {
                entity.setPurchaseLevelName(dataDictionaryDO.getName());
            }
        }

        ActionResult<String> dataDictionaryDOId = fastGenClient.textGuid();
        if (dataDictionaryDOId == null || dataDictionaryDOId.getCode() != 0)
        {
            return null;
        }
        //内部主键
        entity.setId(dataDictionaryDOId.getValue());
        //销售订单
        entity.setSaleNo(genDocumentService.getDocumentNo(BillDesc.SaleNo));
        model.getHeaderInfo().setSaleNo(entity.getSaleNo());
        //小数转换整数
        rounding(entity);
        entity.setTotalDiscountPrice(new BigDecimal("0"));
        entity.setTotalSettlementPrice(new BigDecimal("0"));
        List<SaleIntentionDetailDO> detailDOList = new ArrayList<>();
        for (SaleIntentionDetailVO detailVO : model.getMaterialList())
        {
            SaleIntentionDetailDO detailDO = new SaleIntentionDetailDO();
            BeanUtils.copyProperties(detailVO, detailDO);
            ActionResult<String> detailDOId = fastGenClient.textGuid();
            if (detailDOId == null || detailDOId.getCode() != 0)
            {
                return null;
            }
            detailDO.setId(detailDOId.getValue());
            detailDO.setSaleIntentionId(entity.getId());
            detailDO.setSaleNo(entity.getSaleNo());
            getDetailDO(model, detailDO);

            if(detailDO.getUnitPriceAfterAdjust() == null){
                detailDO.setUnitPriceAfterAdjust(BigDecimal.ZERO);
                detailDO.setTotalPriceAfterAdjust(BigDecimal.ZERO);
            }

            if(detailDO.getUnitPriceAfterAdjust() == null || detailDO.getUnitPriceAfterAdjust().compareTo(BigDecimal.ZERO) == 0){
                entity.setIsSynPrice(1);
            }

            if(!StringUtil.isNullOrEmpty(detailDO.getPriceSchemeId())){
                MarketingActivityDO marketingActivityDO=marketingActivityMapper.item(detailDO.getPriceSchemeId());
                if(marketingActivityDO==null){
                    model.setRet(ErrorCode.AcivityNotFound);
                    throw new Exception("价格策略不存在");
                }
                if(marketingActivityDO.getState().equals(0)){
                    model.setRet(ErrorCode.AcivityDisabled);
                    throw new Exception("价格策略未启用");
                }
            }

            saleIntentionDetailMapper.insert(detailDO);

            detailDOList.add(detailDO);

            entity.setTotalSettlementPrice(entity.getTotalSettlementPrice().add(detailDO.getApplyTotalPrice()));

            entity.setTotalDiscountPrice(entity.getTotalDiscountPrice().add(detailDO.getTotalPriceAfterAdjust()));


        }
        if(entity.getPurchaseLevelId()==null || !"1".equals(entity.getPurchaseLevelId())) {
            //判断客户额度是否足够
            CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(entity.getSupplierOrgId(), entity.getPurchaseOrgId());
            if (dealerDO == null) {
                throw new Exception("未找到客户记录");
            }
            if (dealerDO.getEnableLimit() == 1) {
                BigDecimal price = BigDecimal.ZERO;
                if (entity.getTotalDiscountPrice() != null) {
                    price = entity.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                }
                BigDecimal totalPrice = dealerDO.getUsedLimit().add(price);
                if (totalPrice.compareTo(dealerDO.getTotalLimit()) > 0) {
                    throw new Exception("客户额度已超额");
                } else {
                    dealerDO.setUsedLimit(totalPrice);
                    companyDealerMapper.update(dealerDO);
                    entity.setIsLimit(1);
                }
            }
        }

        saleIntentionMapper.insert(entity);

        String deliveryNo = this.balanceAdd(entity, detailDOList);

        if(entity.getCreateType().equals(1))
        {
            //手动创建的单据，不需要更改采购单状态
            return  deliveryNo;
        }

        PurchaseRequestDO purchaseRequestDO = new PurchaseRequestDO();
        purchaseRequestDO.setBillNo(entity.getPurchaseNo());
        if("0".equals(entity.getStatus()))
        {
            //已保存
            purchaseRequestDO.setIsSale(1);
        }
        else
        {
            //已提交
            purchaseRequestDO.setIsSale(2);
        }
        purchaseRequestService.updateBySaleBill(purchaseRequestDO);

        return deliveryNo;
    }

    private String balanceAdd(SaleIntentionDO entity, List<SaleIntentionDetailDO> detailDOList)throws Exception{
        //生成发货通知单
        DeliveryNoteAddVO deliveryNoteAddVO = new DeliveryNoteAddVO();
        DeliveryNoteVO noteVO = new DeliveryNoteVO();
        List<DeliveryNoteDetailVO> noteDetailVOList = new ArrayList<>();
        BeanUtils.copyProperties(entity, noteVO);
        noteVO.setDeliveryNo(genDocumentService.getDocumentNo(BillDesc.DeliveryNo));

        CompanyDealerDO companyDealer = companyDealerMapper.itemByOrgId(entity.getSupplierOrgId(), entity.getPurchaseOrgId());
        if (null != companyDealer) {
            noteVO.setDelivery(companyDealer.getDealerCode());
            noteVO.setSold(companyDealer.getDealerCode());
        }
        noteVO.setAddress(entity.getReceiveAddress());
        noteVO.setNote(entity.getRemark());
        noteVO.setDistributionChannelName("内销");
        noteVO.setPayConditionName("全款提货");
        noteVO.setStatus(String.valueOf(DeliveryStatus.Submit.getCode()));
        noteVO.setTotalDiscountPrice(noteVO.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        noteVO.setTotalSettlementPrice(noteVO.getTotalSettlementPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        for(SaleIntentionDetailDO detailDO : detailDOList){
            DeliveryNoteDetailVO noteDetailVO = new DeliveryNoteDetailVO();
            BeanUtils.copyProperties(detailDO, noteDetailVO);
            noteDetailVO.setDeliveryQty(noteDetailVO.getAmountAfterAdjust());
            noteDetailVO.setSendQty(BigDecimal.ZERO);
            noteDetailVO.setInventoryOutAmount(BigDecimal.ZERO);
            noteDetailVO.setSendNumber(BigDecimal.ZERO);
            noteDetailVO.setDeliveryDate(detailDO.getRequestDeliveryDate());
            noteDetailVO.setPrice(noteDetailVO.getPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
            noteDetailVO.setApplyTotalPrice(noteDetailVO.getApplyTotalPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
            noteDetailVO.setUnitPriceAfterAdjust(noteDetailVO.getUnitPriceAfterAdjust().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
            noteDetailVO.setTotalPriceAfterAdjust(noteDetailVO.getTotalPriceAfterAdjust().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
            noteDetailVOList.add(noteDetailVO);
        }
        deliveryNoteAddVO.setHeaderInfo(noteVO);
        deliveryNoteAddVO.setMaterialList(noteDetailVOList);
        deliveryNoteService.add(deliveryNoteAddVO, noteVO.getCreatorId(), noteVO.getSupplierOrgId(),false);
        return noteVO.getDeliveryNo();
    }

    /**
     * 修改销售意向单退货状态
     *
     * @param saleNo String
     * @param status Integer
     * @return ErrorCode
     */
    public ErrorCode updateReturnStatus(String saleNo, Integer status)
    {
     saleIntentionMapper.updateReturnStatus(saleNo, status);

      saleIntentionDetailMapper.updateReturnStatus(saleNo, status);

        return ErrorCode.Success;
    }

    public ErrorCode updateDeliveryDate(SaleIntentionDetailVO intentionDetailVO, String orgId){
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.itemByNo(intentionDetailVO.getSaleNo(), orgId);
        if(saleIntentionDO == null){
            return ErrorCode.IllegalArument;
        }
        SaleIntentionDetailDO intentionDetailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(saleIntentionDO.getId(), intentionDetailVO.getMaterialsNo());
        if(intentionDetailDO == null){
            return ErrorCode.IllegalArument;
        }
        intentionDetailDO.setDeliveryDate(intentionDetailVO.getDeliveryDate());
        intentionDetailDO.setDeliveryCreateDate(new Date());
        intentionDetailDO.setDeliveryCreateId(intentionDetailVO.getDeliveryCreateId());
        intentionDetailDO.setDeliveryCreateName(intentionDetailVO.getDeliveryCreateName());
        return saleIntentionDetailMapper.update(intentionDetailDO)>0?ErrorCode.Success:ErrorCode.Failure;
    }

    public ErrorCode updateLackRemark(SaleIntentionDetailVO intentionDetailVO, String orgId){
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.itemByNo(intentionDetailVO.getSaleNo(), orgId);
        if(saleIntentionDO == null){
            return ErrorCode.IllegalArument;
        }
        SaleIntentionDetailDO intentionDetailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(saleIntentionDO.getId(), intentionDetailVO.getMaterialsNo());
        if(intentionDetailDO == null){
            return ErrorCode.IllegalArument;
        }
        intentionDetailDO.setLackRemark(intentionDetailVO.getLackRemark());
        intentionDetailDO.setLackCreateId(intentionDetailVO.getLackCreateId());
        return saleIntentionDetailMapper.update(intentionDetailDO)>0?ErrorCode.Success:ErrorCode.Failure;
    }

    @Transactional(rollbackFor = Exception.class)
    public synchronized ErrorCode update(SaleAddVO model, String orgId, String userId, String userName) throws Exception
    {
        model.setRet(ErrorCode.Failure);
        SaleIntentionVO headerInfo = model.getHeaderInfo();
        SaleIntentionDO entity = saleIntentionMapper.item(headerInfo.getId());
        if(entity==null){
            return ErrorCode.IllegalArument;
        }
        if(entity.getReceiveAddress()!=null && !entity.getReceiveAddress().equals(headerInfo.getReceiveAddress())){
            headerInfo.setAddressCode(StringUtils.EMPTY);
        }
        takeDecimals(headerInfo);
        BeanUtils.copyProperties(headerInfo, entity);
        Integer forward = headerInfo.getForward();
        forward = forward == null ? ForwardBarcodeLableEnum.NO_FORWARD_BARCODE.getLable() : forward;
        entity.setForward(forward);
        entity.setTotalDiscountPrice(new BigDecimal("0"));
        entity.setTotalSettlementPrice(new BigDecimal("0"));
        List<SaleIntentionDetailDO> detailDOLists=saleIntentionDetailMapper.list(entity.getId());
        saleIntentionDetailMapper.remove(headerInfo.getId());
        if(!StringUtil.isNullOrEmpty(headerInfo.getPurchaseLevelId())){
            DataDictionaryDO dataDictionaryDO = dataDictionaryMapper.itemByCode("CGJB", headerInfo.getPurchaseLevelId());
            if (dataDictionaryDO != null)
            {
                entity.setPurchaseLevelName(dataDictionaryDO.getName());
            }
        }
        //需求http://10.90.1.198/zentao/story-view-2909.html
        //编辑的时候如果新增了零件，则需要生成新的行号（包括先删除再添加回来的也算是新增的零件，此时前端传过来的数据中行号字段值是空的）
        generalNewMateiralsLineNo(model);
        for (SaleIntentionDetailVO detailVO : model.getMaterialList())
        {
            SaleIntentionDetailDO saleIntentionDetailDO=new SaleIntentionDetailDO();
            BeanUtils.copyProperties(detailVO,saleIntentionDetailDO);
            if(detailDOLists.contains(saleIntentionDetailDO)){
                detailDOLists.remove(saleIntentionDetailDO);
            }
            if (!StringUtil.isNullOrEmpty(detailVO.getPriceSchemeId())) {
                MarketingActivityDO marketingActivityDO = marketingActivityMapper.item(detailVO.getPriceSchemeId());
                if (marketingActivityDO == null) {
                    model.setRet(ErrorCode.AcivityNotFound);
                    throw new Exception("价格方案不存在");
                }
                if (marketingActivityDO.getState() == 0) {
                    model.setRet(ErrorCode.AcivityDisabled);
                    throw new Exception("价格方案已禁用");
                }
            }
            SaleIntentionDetailDO detailDO = new SaleIntentionDetailDO();
            BeanUtils.copyProperties(detailVO, detailDO);
            ActionResult<String> detailDOId = fastGenClient.textGuid();
            if (detailDOId == null || detailDOId.getCode() != 0)
            {
                return ErrorCode.Failure;
            }
            detailDO.setId(detailDOId.getValue().toString());
            detailDO.setSaleIntentionId(headerInfo.getId());
            detailDO.setSaleNo(headerInfo.getSaleNo());
            getDetailDO(model, detailDO);

            if(detailDO.getUnitPriceAfterAdjust() == null){
                detailDO.setUnitPriceAfterAdjust(BigDecimal.ZERO);
                detailDO.setTotalPriceAfterAdjust(BigDecimal.ZERO);
            }

            if(detailDO.getUnitPriceAfterAdjust() == null || detailDO.getUnitPriceAfterAdjust().compareTo(BigDecimal.ZERO) == 0){
                entity.setIsSynPrice(1);
            }

            saleIntentionDetailMapper.insert(detailDO);
            entity.setTotalSettlementPrice(entity.getTotalSettlementPrice().add(detailDO.getApplyTotalPrice()));
            entity.setTotalDiscountPrice(entity.getTotalDiscountPrice().add(detailDO.getTotalPriceAfterAdjust()));

        }
        if(!CollectionUtils.isEmpty(detailDOLists)){
            for(SaleIntentionDetailDO sidDO:detailDOLists){
                SaleIntentionDetailVO saleIntentionDetail=new SaleIntentionDetailVO();
                BeanUtils.copyProperties(sidDO,saleIntentionDetail);
                saleIntentionDetail.setDeleteReason(model.getDeleteReason());
                saleIntentionDeleteReasonService.deleteReason(saleIntentionDetail,orgId,userId,userName);
            }
        }

        //编辑零件详情，先清空之前数据(只有手动创建的销售意向才能编辑零件详情)
        if (headerInfo.getCreateType() == 0){
            PurchaseRequestDO purchaseRequestDO = new PurchaseRequestDO();
            purchaseRequestDO.setBillNo(entity.getPurchaseNo());
            if("0".equals(entity.getStatus())){
                //已保存
                purchaseRequestDO.setIsSale(1);
            }
            else{
                //已提交
                purchaseRequestDO.setIsSale(2);
            }
            purchaseRequestService.updateBySaleBill(purchaseRequestDO);
        }
        if(entity.getPurchaseLevelId()==null || !"1".equals(entity.getPurchaseLevelId())) {
            //判断客户额度是否足够
            SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(entity.getId());
            if (saleIntentionDO == null) {
                throw new Exception("未找到主记录");
            }
            CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(entity.getSupplierOrgId(), entity.getPurchaseOrgId());
            if (dealerDO == null) {
                throw new Exception("未找到客户记录");
            }
            if (dealerDO.getEnableLimit() == 1 || saleIntentionDO.getIsLimit() == 1) {
                BigDecimal oldPrice = BigDecimal.ZERO;
                if (saleIntentionDO.getTotalDiscountPrice() != null) {
                    oldPrice = saleIntentionDO.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                }
                BigDecimal newPrice = BigDecimal.ZERO;
                if (entity.getTotalDiscountPrice() != null) {
                    newPrice = entity.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                }
                BigDecimal totalPrice;
                if (saleIntentionDO.getIsLimit() == 0) {
                    totalPrice = dealerDO.getUsedLimit().add(newPrice);
                } else {
                    totalPrice = dealerDO.getUsedLimit().subtract(oldPrice).add(newPrice);
                }
                if (totalPrice.compareTo(dealerDO.getTotalLimit()) > 0) {
                    throw new Exception("客户额度已超额");
                } else {
                    dealerDO.setUsedLimit(totalPrice);
                    companyDealerMapper.update(dealerDO);
                    entity.setIsLimit(1);
                }
            }
        }

        //编辑表头信息
        saleIntentionMapper.update(entity);
        //更新销售订单对应的发货通知单中零件行号与销售订单行号不同的数据中的行号
        updateDeliveryNoteMaterialsLineNo(entity.getSaleNo());
        return ErrorCode.Success;
    }

    /**
     * @Des 更新销售订单对应的发货通知单中零件行号与销售订单行号不同的数据中的行号
     * @Date 2021/4/22 11:30
     * @Author wangzhaoyu
     * @Param [saleNo]
     * @Return void
     */
    private void updateDeliveryNoteMaterialsLineNo(String saleNo) {
        if(StringUtils.isEmpty(saleNo)){
            return;
        }
        deliveryNoteMapper.updateDeliveryNoteMaterialsLineNo(saleNo);
    }

    /**
     * @Des
    //需求http://10.90.1.198/zentao/story-view-2909.html
    //编辑的时候如果新增了零件，则需要生成新的行号（包括先删除再添加回来的也算是新增的零件，此时前端传过来的数据中行号字段值是空的），
     * @Date 2021/4/21 18:10
     * @Author wangzhaoyu
     * @Param [model]
     * @Return void
     */
    private void generalNewMateiralsLineNo(SaleAddVO model) {
        if(model == null){
            return ;
        }
        List<SaleIntentionDetailVO> materialList = model.getMaterialList();
        if(CollectionUtils.isEmpty(materialList)){
            return ;
        }
        // 如果没有行号为空的则直接跳出
        boolean allHaveLineNo = materialList.stream().allMatch(detail -> detail.getLineNo() != null);
        if(allHaveLineNo){
            return ;
        }
        // 获取当前最大的行号
        Integer existsMaxLineNo = getExistsMaxLineNo(materialList);
        // 遍历集合，没有行号的则使用最大行号进行赋值
        for(SaleIntentionDetailVO saleIntentionDetail : materialList){
            Integer lineNo = saleIntentionDetail.getLineNo();
            if(lineNo != null){
                continue;
            }
            existsMaxLineNo++;
            saleIntentionDetail.setLineNo(existsMaxLineNo);
        }
    }

    /**
     * @Des 获取现存的最大行号
     * @Date 2021/4/22 9:13
     * @Author wangzhaoyu
     * @Param [materialList]
     * @Return java.lang.Integer
     */
    private Integer getExistsMaxLineNo(List<SaleIntentionDetailVO> materialList){
        Integer maxLineNo = 0;
        for(SaleIntentionDetailVO detailVO : materialList){
            Integer lineNo = detailVO.getLineNo();
            if(lineNo == null){
                continue;
            }
            if(maxLineNo < lineNo){
                maxLineNo = lineNo;
            }
        }
        return maxLineNo;
    }

    private void getDetailDO(SaleAddVO model, SaleIntentionDetailDO detailDO)
    {
        detailDO.setPrice(rounding(detailDO.getPrice()));
        //计算小计
        detailDO.setApplyTotalPrice(detailDO.getQty().multiply(detailDO.getPrice()));
        //计算调整后小计
        detailDO.setUnitPriceAfterAdjust(rounding(detailDO.getUnitPriceAfterAdjust()));
        if (detailDO.getUnitPriceAfterAdjust().equals(new BigDecimal(0)))
        {
            detailDO.setUnitPriceAfterAdjust(detailDO.getPrice());
        }
        detailDO.setTotalPriceAfterAdjust(detailDO.getAmountAfterAdjust() == null ? new BigDecimal(0) : detailDO.getAmountAfterAdjust().multiply(detailDO.getUnitPriceAfterAdjust()));
        detailDO.setHandselAmount(rounding(detailDO.getHandselAmount()));
        detailDO.setInformedAmount(formatDecimal(detailDO.getInformedAmount()));
        detailDO.setInventoryOutAmount(formatDecimal(detailDO.getInventoryOutAmount()));
    }

    private BigDecimal formatDecimal(BigDecimal value) {
        return null == value ? BigDecimal.ZERO : value;
    }


    @Transactional(rollbackFor = Exception.class)
    public ErrorCode remove(String id, String deleteReason, String orgId, String userId,String userName)throws Exception
    {
        SaleIntentionDO entity = saleIntentionMapper.item(id);
        if(entity == null){
            return ErrorCode.IllegalArument;
        }
        DeliveryNoteVO model = new DeliveryNoteVO();
        model.setSaleNo(entity.getSaleNo());
        model.setSupplierOrgId(entity.getSupplierOrgId());
        List<DeliveryNoteDO> list = deliveryNoteMapper.list(model);
        if(!ListUtil.isNullOrEmpty(list)){
            throw new Exception("只能删除未建发货通知单的销售意向单");
        }
        saleIntentionMapper.remove(id);
        List<SaleIntentionDetailDO> detailDOList=saleIntentionDetailMapper.list(id);
        for(SaleIntentionDetailDO saleIntentionDetailDO:detailDOList){
            SaleIntentionDetailVO saleIntentionDetailVO=new SaleIntentionDetailVO();
            BeanUtils.copyProperties(saleIntentionDetailDO,saleIntentionDetailVO);
            saleIntentionDetailVO.setDeleteReason(deleteReason);
            saleIntentionDeleteReasonService.deleteReason(saleIntentionDetailVO,orgId,userId,userName);
        }

         if(entity.getCreateType()!=null&&entity.getCreateType()!=1){
            PurchaseRequestDO purchaseRequestDO = new PurchaseRequestDO();
            purchaseRequestDO.setBillNo(entity.getPurchaseNo());
            purchaseRequestDO.setIsSale(0);
            purchaseRequestService.updateBySaleBill(purchaseRequestDO);
        }

        //更新客户额度
        CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(entity.getSupplierOrgId(), entity.getPurchaseOrgId());
        if(dealerDO == null){
            throw new Exception("未找到客户记录");
        }
        if(entity.getIsLimit() == 1){
            if(entity.getTotalDiscountPrice() == null){
                entity.setTotalDiscountPrice(BigDecimal.ZERO);
            }
            BigDecimal price = entity.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
            if(dealerDO.getUsedLimit().compareTo(price) < 0){
                throw new Exception("更新客户额度失败");
            }
            dealerDO.setUsedLimit(dealerDO.getUsedLimit().subtract(price));
            companyDealerMapper.update(dealerDO);
        }
        return ErrorCode.Success;
    }

    public SaleAddVO item(String saleId,boolean isForDeliveryNote) throws Exception {
        SaleAddVO result = new SaleAddVO();
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(saleId);
        saleIntentionDO.setCashShortAndOver(DecimalUtil.fen2yuan(saleIntentionDO.getCashShortAndOver()));
        if (saleIntentionDO == null){
            return result;
        }

        //采购方
        String purchaseOrgId = saleIntentionDO.getPurchaseOrgId();
        //供货方
        String supplierOrgId = saleIntentionDO.getSupplierOrgId();
        //供应商（目标主机厂）--进出口使用
        String targetOrgId = saleIntentionDO.getTargetOrgId();

        SaleIntentionVO saleIntentionVO = new SaleIntentionVO();
        BeanUtils.copyProperties(saleIntentionDO, saleIntentionVO);
        Integer forward = saleIntentionDO.getForward();
        forward = forward == null ? ForwardBarcodeLableEnum.NO_FORWARD_BARCODE.getLable() : forward;
        saleIntentionVO.setForward(forward);
        takeDecimals(saleIntentionVO);
        CompanyInfoDO companyInfoDO = companyInfoMapper.item(supplierOrgId);
        if(companyInfoDO != null){
            saleIntentionVO.setIsUrgentPrice(companyInfoDO.getIsUrgentPrice());
        }else{
            saleIntentionVO.setIsUrgentPrice(0);
        }

        //校验供应商是否为平台用户
        if (StringUtils.isNotEmpty(targetOrgId)){
            CompanySupplierDO supplierDO = companySupplierMapper.itemBySupplierOrgId(supplierOrgId, targetOrgId);
            if (supplierDO == null){
                throw new Exception("未找到供应商记录");
            }
            saleIntentionVO.setIsPlatCompany(supplierDO.getIsPlatCompany());
        }

        result.setHeaderInfo(saleIntentionVO);
        List<SaleIntentionDetailVO> listVO = new ArrayList<>();
        List<SaleIntentionDetailDO> listDO = new ArrayList<>();
        if(isForDeliveryNote){
            listDO=saleIntentionDetailMapper.listForDeliveryNote(saleId);
        }else {
            listDO= saleIntentionDetailMapper.listWithRownum(saleId);
        }

        EnableAndOccupyVO enableAndOccupyVO;
        //价格方案批量查询
        Map<String, List<MarketingActivityPriceVO>> priceVOMap = new HashMap<>();
        List<String> materialsNos = listDO.stream().map(SaleIntentionDetailDO::getMaterialsNo).distinct().collect(Collectors.toList());
        materialsNos = CollectionUtils.isEmpty(materialsNos) ? Lists.newArrayList("-1") : materialsNos;
        List<MarketingActivityPriceVO> priceVOList;
        if (StringUtils.isNotEmpty(targetOrgId)){//查询主机厂对进出口价格方案
            priceVOList = marketingActivityService.activityPrice4Batch(supplierOrgId, targetOrgId, materialsNos);
        } else {
            priceVOList = marketingActivityService.activityPrice4Batch(purchaseOrgId, supplierOrgId, materialsNos);
        }
        if (CollectionUtils.isNotEmpty(priceVOList)){
            priceVOMap = priceVOList.stream().collect(Collectors.groupingBy(MarketingActivityPriceVO::getMaterialsNo));
        }

        for (SaleIntentionDetailDO entity : listDO) {
            SaleIntentionDetailVO model = new SaleIntentionDetailVO();
            BeanUtils.copyProperties(entity, model);
            model.setPrice(takeDecimals(model.getPrice()));
            model.setApplyTotalPrice(takeDecimals(model.getApplyTotalPrice()));
            model.setUnitPriceAfterAdjust(takeDecimals(model.getUnitPriceAfterAdjust()));
            model.setTotalPriceAfterAdjust(takeDecimals(model.getTotalPriceAfterAdjust()));
            model.setHandselAmount(model.getHandselAmount());
            model.setInformedAmount(model.getInformedAmount());
            model.setInventoryOutAmount(model.getInventoryOutAmount());
            enableAndOccupyVO = warehouseInventoryService.findEnableAndOccupyNum(model.getMaterialsNo(), saleIntentionDO.getSupplierOrgId(), null);
            if(enableAndOccupyVO != null){
                BeanUtils.copyProperties(enableAndOccupyVO, model);
            }
//            MaterialLocationRelationVO materialLocationRelationVO=new MaterialLocationRelationVO();
//            materialLocationRelationVO.setMaterialNo(entity.getMaterialsNo());
//            materialLocationRelationVO.setOrgId(saleIntentionDO.getSupplierOrgId());
            String materialsNo = model.getMaterialsNo();
            //零件价格方案
            List<MarketingActivityPriceVO> marketingActivityDOList = new ArrayList<>();

            PriMaterialsDO priMaterialsDO;
            if (StringUtils.isNotEmpty(targetOrgId)){//进出口手动创建选择目标主机厂
                priMaterialsDO = priMaterialsMapper.itemByNo(materialsNo, targetOrgId);
                if(priMaterialsDO == null) {
                    priMaterialsDO = priMaterialsMapper.itemByNo(materialsNo, supplierOrgId);
                }
            }else {
                priMaterialsDO = priMaterialsMapper.itemByNo(materialsNo, supplierOrgId);
            }

            if(priMaterialsDO == null) {
                priMaterialsDO = priMaterialsMapper.itemOemByNo(materialsNo, purchaseOrgId);
            }
            if (null == priMaterialsDO) {
                throw new Exception(supplierOrgId + "未查询到零件号为"+ materialsNo +"的零件");
            }
            model.setStandardPrice(DecimalUtil.roundDecimal4Output(priMaterialsDO.getStandardPrice()));
            MaterialsVO mv = priMaterialsMapper.selectMinimumBuy(saleIntentionDO.getSupplierOrgId(), materialsNo);
            if(mv!=null){
                model.setIsMinimumBuy(mv.getIsMinimumBuy());
                model.setMinimumBuy(mv.getMinimumBuy());
            }

            //价格方案列表
            if (priceVOMap.containsKey(materialsNo)){
                model.setMarketingActivityPriceVOList(priceVOMap.get(materialsNo));
            }

            listVO.add(model);
        }
        result.setMaterialList(listVO);
        return result;
    }

    public SaleAddVO itemSaleInfo(String saleId)
    {
        SaleAddVO result = new SaleAddVO();
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(saleId);
        SaleIntentionVO saleIntentionVO = new SaleIntentionVO();
        BeanUtils.copyProperties(saleIntentionDO, saleIntentionVO);
        if (saleIntentionDO == null)
        {
            return result;
        }
        takeDecimals(saleIntentionVO);
        CompanyInfoDO companyInfoDO = companyInfoMapper.item(saleIntentionDO.getSupplierOrgId());
        if(companyInfoDO != null){
            saleIntentionVO.setIsUrgentPrice(companyInfoDO.getIsUrgentPrice());
        }else{
            saleIntentionVO.setIsUrgentPrice(0);
        }
        result.setHeaderInfo(saleIntentionVO);
        List<SaleIntentionDetailVO> listVO = new ArrayList<>();
        List<SaleIntentionDetailDO> listDO = new ArrayList<>();
        listDO= saleIntentionDetailMapper.listWithRownum(saleId);
        EnableAndOccupyVO enableAndOccupyVO;
        for (SaleIntentionDetailDO entity : listDO)
        {
            SaleIntentionDetailVO model = new SaleIntentionDetailVO();
            BeanUtils.copyProperties(entity, model);
            model.setPrice(takeDecimals(model.getPrice()));
            model.setApplyTotalPrice(takeDecimals(model.getApplyTotalPrice()));
            model.setUnitPriceAfterAdjust(takeDecimals(model.getUnitPriceAfterAdjust()));
            model.setTotalPriceAfterAdjust(takeDecimals(model.getTotalPriceAfterAdjust()));
            model.setHandselAmount(model.getHandselAmount());
            model.setInformedAmount(model.getInformedAmount());
            model.setInventoryOutAmount(model.getInventoryOutAmount());

            MaterialLocationRelationVO materialLocationRelationVO=new MaterialLocationRelationVO();
            materialLocationRelationVO.setMaterialNo(entity.getMaterialsNo());
            materialLocationRelationVO.setOrgId(saleIntentionDO.getSupplierOrgId());
            listVO.add(model);
        }
        result.setMaterialList(listVO);
        return result;
    }

    /**
     * @Des 根据销售订单创建采购单时查询销售订单信息
     * @Date 2021/4/1 15:49
     * @Author wangzhaoyu
     * @Param [saleId]
     * @Return xcmg.device.service.vo.sale.SaleAddVO
     */
    public SaleAddVO purchaseCreateQuerySaleIntention(String saleId) throws Exception {
        SaleAddVO result = new SaleAddVO();
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(saleId);
        if (saleIntentionDO == null){
            return result;
        }
        SaleIntentionVO saleIntentionVO = new SaleIntentionVO();
        BeanUtils.copyProperties(saleIntentionDO, saleIntentionVO);
        Integer forward = saleIntentionDO.getForward();
        forward = forward == null ? ForwardBarcodeLableEnum.NO_FORWARD_BARCODE.getLable() : forward;
        saleIntentionVO.setForward(forward);
        //新建发货通知单选择销售订单时，返回的尾差金额为  销售订单尾差金额-已生成的发货通知单的尾差金额
        BigDecimal cashShortAndOver = assembleCashShortAndOver(saleIntentionDO.getCashShortAndOver(), saleIntentionDO.getSaleNo());
        saleIntentionVO.setCashShortAndOver(cashShortAndOver);
        takeDecimals(saleIntentionVO);
        String supplierOrgId = saleIntentionDO.getSupplierOrgId();
        CompanyInfoDO companyInfoDO = companyInfoMapper.item(supplierOrgId);
        if(companyInfoDO != null){
            saleIntentionVO.setIsUrgentPrice(companyInfoDO.getIsUrgentPrice());
        }else{
            saleIntentionVO.setIsUrgentPrice(0);
        }
        result.setHeaderInfo(saleIntentionVO);
        List<SaleIntentionDetailVO> listVO = new ArrayList<>();
        List<SaleIntentionDetailDO> listDO = new ArrayList<>();

        listDO=saleIntentionDetailMapper.listForDeliveryNote(saleId);

        List<String> materialsNos = null;
        if (CollectionUtils.isNotEmpty(listDO)){
            materialsNos = listDO.stream().map(SaleIntentionDetailDO::getMaterialsNo).distinct().collect(Collectors.toList());
            materialsNos = materialsNos.size() > 0 ? materialsNos : Lists.newArrayList("-1");
        }else{
            materialsNos = Collections.EMPTY_LIST;
        }
        //查询英文描述
        Map<String,PubMaterialsDO> pubMaterialsDOMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(materialsNos)){
            List<PubMaterialsDO> pubMaterialsDOList = pubMaterialsMapper.selectByMaterialsNos(materialsNos);
            if (CollectionUtils.isNotEmpty(pubMaterialsDOList)){
                pubMaterialsDOMap = pubMaterialsDOList.stream().collect(Collectors.toMap(PubMaterialsDO::getMaterialsNo, Function.identity(),(k1, k2)->k2));
            }
        }
        Map<String, PriMaterialsDO> priMaterials = getMaterials(materialsNos, saleIntentionDO);

        EnableAndOccupyVO enableAndOccupyVO;
        //价格方案批量查询
        Map<String, List<MarketingActivityPriceVO>> priceVOMap = new HashMap<>();
        materialsNos = CollectionUtils.isEmpty(materialsNos) ? Lists.newArrayList("-1") : materialsNos;
        List<MarketingActivityPriceVO> priceVOList = marketingActivityService.activityPrice4Batch(
                saleIntentionDO.getSupplierOrgId(), saleIntentionDO.getTargetOrgId(), materialsNos);

        if (CollectionUtils.isNotEmpty(priceVOList)){
            priceVOMap = priceVOList.stream().collect(Collectors.groupingBy(MarketingActivityPriceVO::getMaterialsNo));
        }
        for (SaleIntentionDetailDO entity : listDO)
        {
            String materialsNo = entity.getMaterialsNo();
            SaleIntentionDetailVO model = new SaleIntentionDetailVO();
            BeanUtils.copyProperties(entity, model);
            model.setPrice(takeDecimals(model.getPrice()));
            model.setApplyTotalPrice(takeDecimals(model.getApplyTotalPrice()));
            model.setUnitPriceAfterAdjust(takeDecimals(model.getUnitPriceAfterAdjust()));
            model.setTotalPriceAfterAdjust(takeDecimals(model.getTotalPriceAfterAdjust()));
            model.setHandselAmount(model.getHandselAmount());
            model.setInformedAmount(model.getInformedAmount());
            model.setInventoryOutAmount(model.getInventoryOutAmount());
            enableAndOccupyVO = warehouseInventoryService.findEnableAndOccupyNum(model.getMaterialsNo(), supplierOrgId, null);
            if(enableAndOccupyVO != null){
                BeanUtils.copyProperties(enableAndOccupyVO, model);
            }

            //英文描述
            if (pubMaterialsDOMap.containsKey(materialsNo)) {
                model.setMaterialsDesEn(pubMaterialsDOMap.get(materialsNo).getMaterialsDesEn());
            }
            String priceSchemeId = entity.getPriceSchemeId();//价格方案
            MarketingActivityPriceVO priceScheme = saleIntentionMarketingActivity(priceSchemeId, priMaterials, materialsNo);
            model.setMarketingActivityPrice(priceScheme);

            //价格方案列表-批量设置用
            if (priceVOMap.containsKey(materialsNo)){
                model.setMarketingActivityPriceVOList(priceVOMap.get(materialsNo));
            }

            listVO.add(model);
        }
        result.setMaterialList(listVO);
        return result;
    }

    private Map<String,PriMaterialsDO> getMaterials(List<String> materialsNos,SaleIntentionDO saleIntentionDO){
        String orgId = saleIntentionDO.getTargetOrgId();

        if (StringUtils.isEmpty(orgId)){
            orgId = saleIntentionDO.getSupplierOrgId();
        } else {
            CompanySupplierDO companySupplierDO = companySupplierMapper.itemBySupplierOrgId(saleIntentionDO.getSupplierOrgId(), orgId);
            if (null != companySupplierDO && !companySupplierDO.getIsPlatCompany()) {
                orgId = saleIntentionDO.getSupplierOrgId();
            }
        }
        Map<String,PriMaterialsDO> result = new HashMap<>();
        if(CollectionUtils.isEmpty(materialsNos)){
            return result;
        }
        List<PriMaterialsDO> pubMaterialsDOList = priMaterialsMapper.selectByMaterialsNos(materialsNos,orgId);
        if(CollectionUtils.isNotEmpty(pubMaterialsDOList)){
            for(PriMaterialsDO priMaterialsDO : pubMaterialsDOList){
                result.put(priMaterialsDO.getMaterialsNo(),priMaterialsDO);
            }
        }
        return result;
    }

    private MarketingActivityPriceVO saleIntentionMarketingActivity(String priceSchemeId,Map<String, PriMaterialsDO> priMaterials,String materialsNo) throws Exception {
        MarketingActivityPriceVO priceScheme = new MarketingActivityPriceVO();
        PriMaterialsDO priMaterialsDO=priMaterials.get(materialsNo);
        if(priMaterialsDO == null){
            throw new Exception("零件"+materialsNo+"不存在");
        }
        if(StringUtils.isEmpty(priceSchemeId)){
            return priceScheme;
        }
        priceScheme = marketingActivityMapper.activityPriceDetail(priceSchemeId,materialsNo);
        if(priceScheme == null){
            return priceScheme;
        }
        if(priceScheme.getModeType()==1){
            priceScheme.setDiscountPrice(priceScheme.getPrice());
        }else {
            BigDecimal disPrice = new BigDecimal(0);
            // 价格类型为空，则调整后价格=销售价*折扣
            if (ObjectUtils.isEmpty(priceScheme.getPriceType())){
                if(priMaterialsDO.getPrice() == null) {
                    StringBuffer desBuffer = new StringBuffer();
                    desBuffer.append("零件号").append(priMaterialsDO.getMaterialsNo()).append("没有价格");
                    throw new Exception(desBuffer.toString());
                }
                disPrice = priMaterialsDO.getPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
            }
            // 价格类型为销售价，则调整后价格=销售价*折扣
            if (!ObjectUtils.isEmpty(priceScheme.getPriceType()) && priceScheme.getPriceType().equals(ConstantInfo.PRICE_TYPE_SALE)) {
                if(priMaterialsDO.getPrice() == null) {
                    StringBuffer desBuffer = new StringBuffer();
                    desBuffer.append("零件号").append(priMaterialsDO.getMaterialsNo()).append("没有价格");
                    throw new Exception(desBuffer.toString());
                }
                disPrice = priMaterialsDO.getPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
            }
            // 价格类型为标准价，则调整后价格=标准价*折扣
            if (!ObjectUtils.isEmpty(priceScheme.getPriceType()) && priceScheme.getPriceType().equals(ConstantInfo.PRICE_TYPE_STANDARD)){
                if(priMaterialsDO.getPrice() == null) {
                    StringBuffer desBuffer = new StringBuffer();
                    desBuffer.append("零件号").append(priMaterialsDO.getMaterialsNo()).append("没有价格");
                    throw new Exception(desBuffer.toString());
                }
                disPrice = priMaterialsDO.getStandardPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
            }
            disPrice = disPrice.multiply(priceScheme.getModeRate());
            priceScheme.setDiscountPrice(disPrice);
        }
        return priceScheme;
    }

    public SaleAddVO itemByDeliveryNote(String saleId) throws Exception {
        SaleAddVO result = new SaleAddVO();
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(saleId);
        if (saleIntentionDO == null){
            return result;
        }
        SaleIntentionVO saleIntentionVO = new SaleIntentionVO();
        BeanUtils.copyProperties(saleIntentionDO, saleIntentionVO);
        Integer forward = saleIntentionDO.getForward();
        forward = forward == null ? ForwardBarcodeLableEnum.NO_FORWARD_BARCODE.getLable() : forward;
        saleIntentionVO.setForward(forward);
        //新建发货通知单选择销售订单时，返回的尾差金额为  销售订单尾差金额-已生成的发货通知单的尾差金额
        BigDecimal cashShortAndOver = assembleCashShortAndOver(saleIntentionDO.getCashShortAndOver(), saleIntentionDO.getSaleNo());
        saleIntentionVO.setCashShortAndOver(cashShortAndOver);
        takeDecimals(saleIntentionVO);
        CompanyInfoDO companyInfoDO = companyInfoMapper.item(saleIntentionDO.getSupplierOrgId());
        if(companyInfoDO != null){
            saleIntentionVO.setIsUrgentPrice(companyInfoDO.getIsUrgentPrice());
        }else{
            saleIntentionVO.setIsUrgentPrice(0);
        }
        result.setHeaderInfo(saleIntentionVO);
        List<SaleIntentionDetailVO> listVO = new ArrayList<>();
        List<SaleIntentionDetailDO> listDO = new ArrayList<>();

        listDO=saleIntentionDetailMapper.listForDeliveryNote(saleId);

        //查询英文描述
        Map<String,PubMaterialsDO> pubMaterialsDOMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(listDO)){
            List<String> materialsNos = listDO.stream().map(SaleIntentionDetailDO::getMaterialsNo).distinct().collect(Collectors.toList());
            materialsNos = materialsNos.size() > 0 ? materialsNos : Lists.newArrayList("-1");
            List<PubMaterialsDO> pubMaterialsDOList = pubMaterialsMapper.selectByMaterialsNos(materialsNos);
            if (CollectionUtils.isNotEmpty(pubMaterialsDOList)){
                pubMaterialsDOMap = pubMaterialsDOList.stream().collect(Collectors.toMap(PubMaterialsDO::getMaterialsNo, Function.identity(),(k1, k2)->k2));
            }
        }

        EnableAndOccupyVO enableAndOccupyVO;
        for (SaleIntentionDetailDO entity : listDO)
        {
            SaleIntentionDetailVO model = new SaleIntentionDetailVO();
            BeanUtils.copyProperties(entity, model);
            model.setPrice(takeDecimals(model.getPrice()));
            model.setApplyTotalPrice(takeDecimals(model.getApplyTotalPrice()));
            model.setUnitPriceAfterAdjust(takeDecimals(model.getUnitPriceAfterAdjust()));
            model.setTotalPriceAfterAdjust(takeDecimals(model.getTotalPriceAfterAdjust()));
            model.setHandselAmount(model.getHandselAmount());
            model.setInformedAmount(model.getInformedAmount());
            model.setInventoryOutAmount(model.getInventoryOutAmount());
            enableAndOccupyVO = warehouseInventoryService.findEnableAndOccupyNum(model.getMaterialsNo(), saleIntentionDO.getSupplierOrgId(), null);
            if(enableAndOccupyVO != null){
                BeanUtils.copyProperties(enableAndOccupyVO, model);
            }
            MaterialLocationRelationVO materialLocationRelationVO=new MaterialLocationRelationVO();
            materialLocationRelationVO.setMaterialNo(entity.getMaterialsNo());
            materialLocationRelationVO.setOrgId(saleIntentionDO.getSupplierOrgId());
            List<MaterialLocationRelationVO> voList=materialLocationRelationMapper.list(materialLocationRelationVO);
            model.setStockLocationList(voList);
            if(voList==null ||voList.size()<=0){
                model.setStockLocation("暂无默认储位");
            }

            //英文描述
            if (pubMaterialsDOMap.containsKey(entity.getMaterialsNo())) {
                model.setMaterialsDesEn(pubMaterialsDOMap.get(entity.getMaterialsNo()).getMaterialsDesEn());
            }

            listVO.add(model);
        }
        result.setMaterialList(listVO);
        return result;
    }

    /**
     * @Des 创建发货通知单时计算需要显示的尾差金额,返回金额进行分-->元转换
     * @Date 2020/11/12 8:36
     * @Author wangzhaoyu
     * @Param [saleIntentionCashShortAndOver ： 销售订单的尾差金额
     * , saleNo ： 销售订单号]
     * @Return java.math.BigDecimal
     */
    private BigDecimal assembleCashShortAndOver(BigDecimal saleIntentionCashShortAndOver,String saleNo){
        if(saleIntentionCashShortAndOver == null){
            return null;
        }
        // 获取销售订单已经创建的发货通知单的尾差金额之和
        BigDecimal cashShortAndOrverCreated = deliveryNoteMapper.sumCashAndOverBySaleNo(saleNo);
        cashShortAndOrverCreated = cashShortAndOrverCreated == null ? BigDecimal.ZERO : cashShortAndOrverCreated;
        saleIntentionCashShortAndOver = saleIntentionCashShortAndOver.subtract(cashShortAndOrverCreated);
        saleIntentionCashShortAndOver = saleIntentionCashShortAndOver.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : saleIntentionCashShortAndOver;
        saleIntentionCashShortAndOver = DecimalUtil.fen2yuan(saleIntentionCashShortAndOver);
        return saleIntentionCashShortAndOver;
    }

    public List<SaleIntentionDetailVO> findDeliveryNum(String saleNo, String warehouseCode, String orgId) {
        String intentionId = "";
        if(!StringUtil.isNullOrEmpty(saleNo)){
            SaleIntentionDO intentionDO = saleIntentionMapper.itemByNo(saleNo, orgId);
            if(intentionDO != null){
                intentionId = intentionDO.getId();
            }
        }
        List<SaleIntentionDetailDO> listDO = saleIntentionDetailMapper.list(intentionId);
        if (ListUtil.isNullOrEmpty(listDO)) {
            return null;
        }
        List<SaleIntentionDetailVO> voList = new ArrayList<>();
        for (SaleIntentionDetailDO intentionDetailDO : listDO) {
            SaleIntentionDetailVO intentionDetailVO = new SaleIntentionDetailVO();
            intentionDetailVO.setMaterialsNo(intentionDetailDO.getMaterialsNo());
            intentionDetailVO.setDeliveryNum(warehouseDeliveryDetailMapper.findOccupyNum(intentionDetailDO.getMaterialsNo(), orgId, warehouseCode));
            intentionDetailVO.setEnableNum(warehouseInventoryMapper.findEnableNum(intentionDetailDO.getMaterialsNo(), orgId, warehouseCode));
            voList.add(intentionDetailVO);
        }
        return voList;
    }

    /**
     * 刷新销售单退货申请状态<br>
     *     根据销售单零件的退货数量以及退货状态，判断销售单退货申请状态是”未退货“，”部分退货“，”全部退货“
     * @param saleNo  String
     * @return ErrorCode
     */
    public  ErrorCode refreshSaleBillReturnStatus(String saleNo)
    {
        String saleId = saleIntentionMapper.selectIdByNo(saleNo);
        List<SaleIntentionDetailDO> listDO  =saleIntentionDetailMapper.list(saleId);

        int  noReturn = 0;
        int  partReturn = 0;
        int  allReturn = 0;

        for(SaleIntentionDetailDO record:listDO)
        {
            if(null==record.getIsReturn() || record.getIsReturn()==0)
            {
                noReturn++;
                continue;
            }
            if(record.getIsReturn()==1)
            {
                partReturn++;
                continue;
            }
            if(record.getIsReturn()==2)
            {
                allReturn++;
                continue;
            }
        }
        SaleIntentionDO saleIntentionDO =    new SaleIntentionDO();
        saleIntentionDO.setId(saleId);
        if(noReturn==listDO.size())//未申请退货
        {
            saleIntentionDO.setApplyReturn(0);
        }
        else if(allReturn==listDO.size())//全部申请退货
        {
            saleIntentionDO.setApplyReturn(2);
        }
        else
        {
            //部分申请退货
            saleIntentionDO.setApplyReturn(1);
        }
        saleIntentionMapper.update(saleIntentionDO);
        return ErrorCode.Success;
    }


    /**
     * 通过销售单号查询销售单信息
     *
     * @param saleNo String
     * @return SaleAddVO
     */
    public SaleAddVO selectByNo(String saleNo)
    {
        String saleId = saleIntentionMapper.selectIdByNo(saleNo);
        return itemSaleInfo(saleId);
    }

    public void export(List<String> saleIds) throws Exception
    {
        List<SaleIntentionVO> voList = new ArrayList<>();
        for (String saleId : saleIds)
        {
            SaleIntentionDO entity = saleIntentionMapper.item(saleId);
            SaleIntentionVO model = new SaleIntentionVO();
            BeanUtils.copyProperties(entity, model);
            takeDecimals(model);
            if (model != null)
            {
                voList.add(model);
            }
        }
        invokeExport(voList);
    }

    public void exportAll(SaleIntentionVO condition) throws Exception
    {
        ////PageHelperPlus.startPage(0, 0, "create_date desc");
        condition.setBillNosList(xcmg.device.infra.StringUtil.splitList(condition.getBillNos()));
        condition.setMaterialsList(xcmg.device.infra.StringUtil.splitList(condition.getMaterialsNo()));
        condition.setPurchaseNamesList(xcmg.device.infra.StringUtil.splitList(condition.getPurchaseNames()));

//===========================原始版本(舍弃)================================================
//        List<SaleIntentionDO> doList = saleIntentionMapper.list(condition);
//        List<SaleIntentionVO> voList = new ArrayList<>();
//        for (SaleIntentionDO entity : doList)
//        {
//            SaleIntentionVO model = new SaleIntentionVO();
//            BeanUtils.copyProperties(entity, model);
//            takeDecimals(model);
//            voList.add(model);
//        }
//        invokeExport(voList);

//==========================优化版-去掉for循环中查询，改为一次join查询(应用)================================
        //PageHelperPlus.startPage(0, 0, "create_date desc");
        List<SaleIntentionExportDO> doList = saleIntentionMapper.findExportList(condition);
        invokeExportNew(doList);


//==========================多线程优化版，每个线程查1000条数据，最后汇总(以后可以考虑使用，目前不需要)===========================
//        List<SaleIntentionExportDO> doList = new ArrayList<>();
//        ThreadPoolExecutor executor = new ThreadPoolExecutor(8, 8, 1000L, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>());
//        Integer count = saleIntentionMapper.findCountExportList(condition);
//        List<Future<List<SaleIntentionExportDO>>> futureList = new ArrayList<>();
//        int pageSize = 1000;
//        int time = count/pageSize + 1;
//        for (int i = 0; i<time ; i++){
//            int pageNum = i;
//            Future<List<SaleIntentionExportDO>> future = executor.submit(new Callable<List<SaleIntentionExportDO>>() {
//                @Override
//                public List<SaleIntentionExportDO> call() throws Exception {
//                    PageHelperPlus.startPage(pageNum + 1, pageSize,"create_date desc");
//                    return saleIntentionMapper.findExportList(condition);
//                }
//            });
//            futureList.add(future);
//        }
//        for (Future<List<SaleIntentionExportDO>> future : futureList) {
//            future.get();
//            doList.addAll(future.get());
//        }
//        invokeExportNew(doList);
    }

    private void invokeExport(List<SaleIntentionVO> voList) throws Exception
    {
        String title = "销售意向数据导出";
        String[] rowsName = new String[]{"序号", "意向单号", "客户名称", "采购单号", "采购级别", "发运方式", "创建方式", "创建人", "制单时间", "发货通知状态", "出库状态","合同号",
        "零件编码","零件名称","单位","申请数量","单价","申请总价","价格方案","调整后数量","调整后单价","调整后总价","创建发货数量",
         "实际出库数量","可用库存","意向占用","发货占用","发货时间","备注", "国家"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs = null;
        for (int i = 0; i < voList.size(); i++) {
            SaleIntentionVO e = voList.get(i);
            takeDecimals(e);
            List<SaleIntentionDetailDO> listDO = saleIntentionDetailMapper.list(e.getId());
            if(listDO==null){
                continue;
            }
            for(int j=0;j<listDO.size();j++){
                SaleIntentionDetailDO d=listDO.get(j);
                EnableAndOccupyVO enableAndOccupyVO = warehouseInventoryService.findEnableAndOccupyNum(d.getMaterialsNo(), e.getSupplierOrgId(), null);
                objs = new Object[rowsName.length];
                objs[0] = i + 1;
                objs[1] = e.getSaleNo();
                objs[2] = e.getPurchaseOrgName();
                objs[3] = e.getPurchaseNo();
                objs[4] = StringUtils.defaultString(e.getPurchaseLevelName()) + (StringUtils.isBlank(e.getPurchaseTypeChildName()) ? "" : ("-" + StringUtils.defaultString(e.getPurchaseTypeChildName())));
                objs[5] = e.getDeliverTypeName();
                objs[6] = getCreateType(e.getCreateType());
                objs[7] = e.getCreateName();
                objs[8] = e.getCreateDate() == null ? "" : DateUtil.formatDateTime(e.getCreateDate());
                objs[9] = getStatusDesc(e.getDeliverStatus());
                objs[10] = getInventoryOutDesc(e.getInventoryOutStatus());
                objs[11] = e.getContract();
                objs[12] = d.getMaterialsNo();
                objs[13] = d.getMaterialsDes();
                objs[14] = d.getUnit();
                objs[15] = d.getQty();
                objs[16] = takeDecimals(d.getPrice());
                objs[17] = takeDecimals(d.getApplyTotalPrice());
                objs[18] = d.getPriceSchemeName();
                objs[19] = d.getAmountAfterAdjust();
                objs[20] = takeDecimals(d.getUnitPriceAfterAdjust());
                objs[21] = takeDecimals(d.getTotalPriceAfterAdjust());
                objs[22] = d.getInformedAmount();
                objs[23] = d.getInventoryOutAmount();
                objs[24]=enableAndOccupyVO.getEnableNum();
                objs[25]=enableAndOccupyVO.getIntentionNum();
                objs[26]=enableAndOccupyVO.getDeliveryNum();
                objs[27] = d.getRequestDeliveryDate() == null ? "" : DateUtil.formatDate(d.getRequestDeliveryDate());
                objs[28] = e.getRemark();
                objs[29] = e.getCountry();
                dataList.add(objs);
            }
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private void invokeExportNew(List<SaleIntentionExportDO> voList) throws Exception
    {
        String title = "销售意向数据导出";
        String[] rowsName = new String[]{"序号", "意向单号", "客户名称", "采购单号", "采购级别", "发运方式", "创建方式", "创建人", "制单时间", "发货通知状态", "出库状态","合同号",
                "零件编码","零件名称","单位","申请数量","单价","申请总价","价格方案","调整后数量","调整后单价","调整后总价","创建发货数量",
                "实际出库数量","可用库存","意向占用","发货占用","发货时间","备注", "国家"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs = null;
        for (int i = 0; i < voList.size(); i++) {
            SaleIntentionExportDO e = voList.get(i);
            takeDecimals(e);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = e.getSaleNo();
            objs[2] = e.getPurchaseOrgName();
            objs[3] = e.getPurchaseNo();
            objs[4] = StringUtils.defaultString(e.getPurchaseLevelName()) + (StringUtils.isBlank(e.getPurchaseTypeChildName()) ? "" : ("-" + StringUtils.defaultString(e.getPurchaseTypeChildName())));
            objs[5] = e.getDeliverTypeName();
            objs[6] = getCreateType(e.getCreateType());
            objs[7] = e.getCreateName();
            objs[8] = e.getCreateDate() == null ? "" : DateUtil.formatDateTime(e.getCreateDate());
            objs[9] = getStatusDesc(e.getDeliverStatus());
            objs[10] = getInventoryOutDesc(e.getInventoryOutStatus());
            objs[11] = e.getContract();
            objs[12] = e.getMaterialsNo();
            objs[13] = e.getMaterialsDes();
            objs[14] = e.getUnit();
            objs[15] = e.getQty();
            objs[16] = takeDecimals(e.getPrice());
            objs[17] = takeDecimals(e.getApplyTotalPrice());
            objs[18] = e.getPriceSchemeName();
            objs[19] = e.getAmountAfterAdjust();
            objs[20] = takeDecimals(e.getUnitPriceAfterAdjust());
            objs[21] = takeDecimals(e.getTotalPriceAfterAdjust());
            objs[22] = e.getInformedAmount();
            objs[23] = e.getInventoryOutAmount();
            objs[27] = e.getRequestDeliveryDate() == null ? "" : DateUtil.formatDate(e.getRequestDeliveryDate());
            objs[28] = e.getRemark();
            objs[29] = e.getCountry();
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private String getCreateType(Integer type){
        if(type==null){
            return "异常";
        }
        if(type==0){
            return "采购申请";
        }else if(type==1){
            return "手动创建";
        }else if(type==2){
            return "外部接口";
        }
        return "其他";
    }


    //替换零件是最后去重操作，直接拷贝xcmg.device.service.sale.SaleIntentionService.deRepeat方法，把里面的setAmountAfterAdjust改掉
    //原因如果单据做过调整，调整了零件的数量，再做零件替换的话amountAftreAdjust会被申请数量qty覆盖掉
    public static List<SaleIntentionDetailVO> materialsReplaceDeRepeat(List<SaleIntentionDetailVO> repeatList)
    {
        if(CollectionUtils.isEmpty(repeatList)){
            return repeatList;
        }
        for  ( int i  = 0 ; i< repeatList.size()-1;i++){
            BigDecimal sum =repeatList.get(i).getQty();
            BigDecimal amountAfterAdjustSum = repeatList.get(i).getAmountAfterAdjust();
            for  ( int j=repeatList.size()-1;j>i;j -- )  {
                if  (repeatList.get(j).equals(repeatList.get(i))||repeatList.get(j).getMaterialsNo().equals(repeatList.get(i).getMaterialsNo())){
                    sum=sum.add(repeatList.get(j).getQty());
                    amountAfterAdjustSum = amountAfterAdjustSum.add(repeatList.get(j).getAmountAfterAdjust());
                    if (StringUtils.isNotEmpty(repeatList.get(j).getIsReplaceMaterial())){
                        repeatList.get(i).setIsReplaceMaterial("1");//替换零件
                        repeatList.get(i).setOriginalMaterialsNo(repeatList.get(j).getOriginalMaterialsNo());
                    }
                    repeatList.remove(j);

                }
            }
            repeatList.get(i).setQty(sum);
            repeatList.get(i).setAmountAfterAdjust(amountAfterAdjustSum);
            repeatList.get(i).setApplyTotalPrice(repeatList.get(i).getPrice()==null?new BigDecimal(0):repeatList.get(i).getPrice().multiply(sum));
            repeatList.get(i).setTotalPriceAfterAdjust(repeatList.get(i).getUnitPriceAfterAdjust() == null ? new BigDecimal(0)
                    : repeatList.get(i).getUnitPriceAfterAdjust().multiply(sum));
        }
        return repeatList;

    }

    //List去重
    public static List<SaleIntentionDetailVO> deRepeat(List<SaleIntentionDetailVO> repeatList)
    {
        if(CollectionUtils.isEmpty(repeatList)){
            return repeatList;
        }
        for  ( int i  = 0 ; i< repeatList.size()-1;i++){
            BigDecimal sum =repeatList.get(i).getQty();
            for  ( int j=repeatList.size()-1;j>i;j -- )  {
                if  (repeatList.get(j).equals(repeatList.get(i))||repeatList.get(j).getMaterialsNo().equals(repeatList.get(i).getMaterialsNo())){
                    sum=sum.add(repeatList.get(j).getQty());
                    repeatList.remove(j);
                }
            }
            repeatList.get(i).setQty(sum);
            repeatList.get(i).setAmountAfterAdjust(sum);
            repeatList.get(i).setApplyTotalPrice(repeatList.get(i).getPrice()==null?new BigDecimal(0):repeatList.get(i).getPrice().multiply(sum));
        }
        return repeatList;

    }


    public FunctionResult importExcel(InputStream in, String dealerOrgId, String orgId, String targetOrgId) throws Exception
    {
        //判断谁是采购方和供方,进出口特殊需判断
        String purchaseOrgId = dealerOrgId;
        String supplierOrgId  = orgId;
        if (StringUtils.isNotEmpty(targetOrgId)){//供应商
            purchaseOrgId = orgId;
            supplierOrgId = targetOrgId;
        }

        //查询代理商信息
        CompanyDealerDO companyDealerDO = companyDealerMapper.itemByOrgId(supplierOrgId, purchaseOrgId);

        FunctionResult result = new FunctionResult();
        HSSFWorkbook wb = new HSSFWorkbook(in);
        HSSFSheet sheet = wb.getSheetAt(0);

        int totalRow = sheet.getLastRowNum();
        if (totalRow < 2)
        {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        int totalCell = sheet.getRow(2).getLastCellNum();
        if (totalCell != 7)
        {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        List<SaleIntentionDetailVO> detailVOList = new ArrayList<>();
        List<SaleIntentionDetailVO> errorDetailVOList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        //批量查询零件价格方案
        Map<String, List<MarketingActivityPriceVO>> priceVOMap = new HashMap<>();
        //导入零件集合
        List<String> materialsNos = new ArrayList<>();
        for (int i = 2; i <= totalRow; i++){
            HSSFRow curRow = sheet.getRow(i);
            if (curRow != null && !isRowEmpty(curRow)) {
                String materialsNo = excelValue(curRow,1);
                materialsNos.add(materialsNo);
            }
        }
        materialsNos = CollectionUtils.isEmpty(materialsNos) ? Lists.newArrayList("-1") : materialsNos;
        List<MarketingActivityPriceVO> priceVOList = marketingActivityService.activityPrice4Batch(purchaseOrgId, supplierOrgId, materialsNos);
        if (CollectionUtils.isNotEmpty(priceVOList)){
            priceVOMap = priceVOList.stream().collect(Collectors.groupingBy(MarketingActivityPriceVO::getMaterialsNo));
        }

        Map<String, MaterialsVO> materialsVOMap = new HashMap<>();
        //批量查询零件
        List<MaterialsVO> materialsVOs = materialsService.itemByNos(materialsNos, supplierOrgId);
        if (CollectionUtils.isNotEmpty(materialsVOs)){
            materialsVOMap = materialsVOs.stream().collect(Collectors.toMap(MaterialsVO::getMaterialsNo, Function.identity(), (k1,k2)->k2));
        }

        for (int i = 2; i <= totalRow; i++) {
            HSSFRow curRow = sheet.getRow(i);
            SaleIntentionDetailVO detailVO = new SaleIntentionDetailVO();
            if (curRow == null || isRowEmpty(curRow)) {
                continue;
            }

            String materialsNo = excelValue(curRow,1);
            String qty = excelValue(curRow,3);
            String price=excelValue(curRow,4);
            String deliveryDate = curRow.getCell(5) == null ? "" : ExcelUtil.getCellStringValue(curRow.getCell(5));
            String machineModel = excelValue(curRow,6);
            if (!isNumber(qty)) {
                qty = "1";
            }

            MaterialsVO materialsVO = null;
            if (materialsVOMap.containsKey(materialsNo)){
                materialsVO = materialsVOMap.get(materialsNo);
            }

            if (materialsVO == null) {
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark("零件不存在");
                errorDetailVOList.add(detailVO);
                continue;
            }
            BigDecimal intQty = new BigDecimal(qty);
            BigDecimal max = new BigDecimal(99999999.99);
            if (intQty.compareTo(max) > 0) {
                intQty = max;
            }
            detailVO.setQty(intQty);
            detailVO.setMaterialsNo(materialsVO.getMaterialsNo());
            detailVO.setMaterialsDes(materialsVO.getMaterialsDes());
            detailVO.setMachineModel(machineModel);
            try
            {
                detailVO.setRequestDeliveryDate(sdf.parse(deliveryDate));
            }
            catch (Exception e)
            {
                LogHelper.fatal(e.getMessage(), e);
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark("日期格式错误");
                errorDetailVOList.add(detailVO);
                continue;
            }
            if(!StringUtil.isNullOrEmpty(price)){
                if(!judgeTwoDecimal(price)){
                    detailVO.setErrorRow(i + 1);
                    detailVO.setRemark("调整后的单价格式错误");
                    errorDetailVOList.add(detailVO);
                    continue;
                }
                detailVO.setUnitPriceAfterAdjust(new BigDecimal(price));
            }
            detailVO.setPrice(materialsVO.getPrice());
            detailVO.setUnit(materialsVO.getUnit());
            detailVO.setAmountAfterAdjust(intQty);
            detailVO.setIsMinimumBuy(materialsVO.getIsMinimumBuy());
            detailVO.setMinimumBuy(materialsVO.getMinimumBuy());
            detailVO.setApplyTotalPrice(detailVO.getPrice() == null ? new BigDecimal(0) : detailVO.getPrice().multiply(detailVO.getQty()));
            //已选价格方案
            MarketingActivityPriceVO marInfo=marketingActivityService.activityPriceModel(companyDealerDO, supplierOrgId, detailVO.getMaterialsNo());
            detailVO.setSettlementPrice(detailVO.getUnitPriceAfterAdjust()==null?materialsVO.getPrice():detailVO.getUnitPriceAfterAdjust());
            if(marInfo != null){
                detailVO.setSettlementPrice(detailVO.getUnitPriceAfterAdjust()==null?marInfo.getDiscountPrice():detailVO.getUnitPriceAfterAdjust());
                detailVO.setPriceSchemeId(marInfo.getActivityId());
                detailVO.setPriceSchemeName(marInfo.getName());
            }
            detailVO.setUnitPriceAfterAdjust(detailVO.getSettlementPrice()==null?BigDecimal.ZERO:detailVO.getSettlementPrice());
            detailVO.setTotalPriceAfterAdjust(detailVO.getUnitPriceAfterAdjust().multiply(detailVO.getQty()));
            EnableAndOccupyVO enableAndOccupyVO = warehouseInventoryService.findEnableAndOccupyNum(detailVO.getMaterialsNo(), supplierOrgId, null);
            if(enableAndOccupyVO!=null){
                detailVO.setIntentionNum(enableAndOccupyVO.getIntentionNum());
                detailVO.setDeliveryNum(enableAndOccupyVO.getDeliveryNum());
                detailVO.setEnableNum(enableAndOccupyVO.getEnableNum());
            }
            //价格方案列表
            if (priceVOMap.containsKey(detailVO.getMaterialsNo())){
                detailVO.setMarketingActivityPriceVOList(priceVOMap.get(detailVO.getMaterialsNo()));
            }
            detailVOList.add(detailVO);
        }

        if (ListUtil.isNullOrEmpty(errorDetailVOList))
        {
            result.setValue(deRepeat(detailVOList));
            result.setCode(ErrorCode.Success);
        }
        else
        {
            result.setValue(errorDetailVOList);
            result.setCode(ErrorCode.IllegalArument);
        }
        return result;
    }
    private String excelValue(HSSFRow curRow,Integer line){
        Cell cell = curRow.getCell(line);
        String cellValue="";
        if (null != cell) {
            int cellType = cell.getCellType();
            log.info("导入零件的单元格格为{}",cellType);
            // 以下是判断数据的类型
            switch (cellType) {
                case HSSFCell.CELL_TYPE_NUMERIC: // 数字
                    DecimalFormat df = new DecimalFormat("0");
                    cellValue = df.format(cell.getNumericCellValue());
                    break;

                case HSSFCell.CELL_TYPE_STRING: // 字符串
                    cellValue = cell.getStringCellValue();
                    break;

                case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
                    cellValue = cell.getBooleanCellValue() + "";
                    break;

                case HSSFCell.CELL_TYPE_FORMULA: // 公式
                    cellValue = cell.getCellFormula() + "";
                    break;

                case HSSFCell.CELL_TYPE_BLANK: // 空值
                    cellValue = "";
                    break;

                case HSSFCell.CELL_TYPE_ERROR: // 故障
                    cellValue = "";
                    break;

                default:
                    cellValue = "";
                    break;
            }
        }
        return cellValue;
    }
    public static boolean isRowEmpty(HSSFRow row) {
        for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
            HSSFCell cell = row.getCell(c);
            if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK&&!StringUtil.isNullOrSpace(ExcelUtil.getCellStringValue(cell)))
            {
                return false;
            }
        }
        return true;
    }

    public static boolean judgeTwoDecimal(Object obj){
        boolean flag = false;
        try {
            if(obj != null){
                String source = obj.toString();
                // 判断是否是整数或者是携带一位或者两位的小数
                Pattern pattern = Pattern.compile("^[+]?([0-9]+(.[0-9]{1,2})?)$");
                if(pattern.matcher(source).matches()){
                    flag = true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    @Transactional
    public ErrorCode updateInformAmount(List<InformVO> informVOList,String orgId)
    {
        if (ListUtil.isNullOrEmpty(informVOList))
        {
            return ErrorCode.IllegalArument;
        }
        SaleIntentionDO saleIntentionDO=saleIntentionMapper.itemByNo(informVOList.get(0).getSaleNo(),orgId);
        if(saleIntentionDO==null){
            return ErrorCode.IllegalArument;
        }
        String status = "2";
        for (InformVO infromVO : informVOList)
        {
            SaleIntentionDetailDO saleIntentionDetailDO = new SaleIntentionDetailDO();
            saleIntentionDetailDO.setMaterialsNo(infromVO.getMaterialsNo());
            saleIntentionDetailDO.setInformedAmount(infromVO.getInformedAmount());
            saleIntentionDetailDO.setSaleNo(infromVO.getSaleNo());

            saleIntentionDetailMapper.updateInformAmount(saleIntentionDetailDO);
        }
        if(saleIntentionDetailMapper.sendAmount(saleIntentionDO.getId()).compareTo(BigDecimal.ZERO)==0){
            status="0";
        }
        else if(saleIntentionDetailMapper.unSendAmount(saleIntentionDO.getId()).compareTo(BigDecimal.ZERO)>0){
            status = "1";
        }

        if (saleIntentionMapper.updateInformStatus(informVOList.get(0).getSaleNo(), status, orgId) == 0)
        {
            return ErrorCode.Failure;
        }
        return ErrorCode.Success;
    }

    public void download() throws Exception
    {
        FileUtil.downLoadFile(response, filePath, templateExcelFileName);
    }

    private String getInventoryOutDesc(String InventoryOut){
        switch (InventoryOut)
        {
            case "0":
            default:
                return "未出库";
            case "1":
                return "部分出库";
            case "2":
                return "已出库";
            case "3":
                return "强制结单";
        }
    }
    private String getStatusDesc(String statusId)
    {
        switch (statusId)
        {
            case "0":
            default:
                return "未开始";
            case "1":
                return "进行中";
            case "2":
                return "已完成";
        }

    }

    private static void rounding(SaleIntentionDO entity)
    {
        if (entity.getTotalDiscountPrice() != null)
        {
            //取整
            entity.setTotalDiscountPrice(entity.getTotalDiscountPrice().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));
        }
        if (entity.getTotalSettlementPrice() != null)
        {
            //取整
            entity.setTotalSettlementPrice(entity.getTotalSettlementPrice().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));
        }
    }

    private static void takeDecimals(SaleIntentionVO model)
    {
        if (model.getTotalDiscountPrice() != null)
        {
            model.setTotalDiscountPrice(model.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        }
        if (model.getTotalSettlementPrice() != null)
        {
            model.setTotalSettlementPrice(model.getTotalSettlementPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        }

    }

    private static void takeDecimals(SaleIntentionExportDO model)
    {
        if (model.getTotalDiscountPrice() != null)
        {
            model.setTotalDiscountPrice(model.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        }
        if (model.getTotalSettlementPrice() != null)
        {
            model.setTotalSettlementPrice(model.getTotalSettlementPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        }

    }

    private static BigDecimal takeDecimals(BigDecimal integer)
    {
        if (integer == null)
        {
            return new BigDecimal(0);
        }
        return integer.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
    }

    private static BigDecimal rounding(BigDecimal decimal)
    {
        if (decimal == null)
        {
            return new BigDecimal(0);
        }
        return decimal.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * @Author: WangKe
     * @Description: 零件出库时更新销售意向单状态
     * @Date: 2018/3/14 0014
     */
    public boolean updateByOutBound(String saleNo, String materailNo, BigDecimal outAmount, String orgId)
    {
        SaleIntentionVO saleIntentionVO = new SaleIntentionVO();
        saleIntentionVO.setSupplierOrgId(orgId);
        saleIntentionVO.setSaleNo(saleNo);
        List<SaleIntentionDO> saleIntentionList = saleIntentionMapper.list(saleIntentionVO);
        if (ListUtil.isNullOrEmpty(saleIntentionList))
        {
            return false;
        }
        SaleIntentionDO saleIntentionDO = saleIntentionList.get(0);
        SaleIntentionDetailDO detailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(saleIntentionDO.getId(), materailNo);
        if (detailDO == null)
        {
            return false;
        }
        detailDO.setInventoryOutAmount(outAmount.add(detailDO.getInventoryOutAmount()));
        if (detailDO.getInventoryOutAmount().compareTo(detailDO.getAmountAfterAdjust()) >= 0)
        {
            detailDO.setInventoryOutStatus("2");
        }
        else
        {
            detailDO.setInventoryOutStatus("1");
        }
        boolean success = saleIntentionDetailMapper.update(detailDO)>0;
        if(!success){
            return false;
        }
        //更新销售意向主表出库状态
        String status = "1";
        if ("2".equals(detailDO.getInventoryOutStatus()))
        {
            List<SaleIntentionDetailDO> detailDOList = saleIntentionDetailMapper.list(saleIntentionDO.getId());
            if (ListUtil.isNullOrEmpty(detailDOList))
            {
                return false;
            }
            status = "2";
            for (SaleIntentionDetailDO intentionDetailDO : detailDOList)
            {
                if (!intentionDetailDO.getMaterialsNo().equals(materailNo) && !"2".equals(intentionDetailDO.getInventoryOutStatus()))
                {
                    status = "1";
                    break;
                }
            }
        }
        saleIntentionDO.setInventoryOutStatus(status);
        return saleIntentionMapper.update(saleIntentionDO) > 0;
    }

    /**
     * @Author: WangKe
     * @Description: 发货通知单手动结单时更新销售意向状态
     * @Date: 2018/6/4 0004
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateByManulFinish(DeliveryNoteDO deliveryNoteDO, String materialNo, String orgId)throws Exception{
        if(deliveryNoteDO == null){
            return false;
        }
        List<DeliveryNoteDetailDO> noteDetailDOList = deliveryNoteDetailMapper.list(deliveryNoteDO.getId());
        if(ListUtil.isNullOrEmpty(noteDetailDOList)){
            return false;
        }
        SaleIntentionVO saleIntentionVO = new SaleIntentionVO();
        saleIntentionVO.setSupplierOrgId(orgId);
        saleIntentionVO.setSaleNo(deliveryNoteDO.getSaleNo());
        List<SaleIntentionDO> saleIntentionList = saleIntentionMapper.list(saleIntentionVO);
        if (ListUtil.isNullOrEmpty(saleIntentionList)){
            return false;
        }
        SaleIntentionDO saleIntentionDO = saleIntentionList.get(0);
        if(saleIntentionDO == null){
            return false;
        }
        List<SaleIntentionDetailDO> intentionDetailDOList = saleIntentionDetailMapper.list(saleIntentionDO.getId());
        if (ListUtil.isNullOrEmpty(intentionDetailDOList)){
            return false;
        }

        BigDecimal sub;
        boolean success;
        boolean enable;
        for(SaleIntentionDetailDO intentionDetailDO : intentionDetailDOList){
            if(!StringUtil.isNullOrEmpty(materialNo) && !materialNo.equals(intentionDetailDO.getMaterialsNo())){
                continue;
            }
            for(DeliveryNoteDetailDO noteDetailDO : noteDetailDOList){
                if(intentionDetailDO.getMaterialsNo().equals(noteDetailDO.getMaterialsNo())){
                    enable = !"2".equals(noteDetailDO.getStatus()) && !"3".equals(noteDetailDO.getStatus());
                    if(enable){
                        sub = noteDetailDO.getDeliveryQty().subtract(noteDetailDO.getInventoryOutAmount());
                        intentionDetailDO.setInformedAmount(intentionDetailDO.getInformedAmount().subtract(sub));
                        success = saleIntentionDetailMapper.update(intentionDetailDO)>0;
                        if(!success){
                            throw new Exception("更新销售意向详情失败");
                        }

                        //更新同一销售意向单下其他发货通知单的计划发货数量
                        success = deliveryNoteDetailMapper.updateSendQty(orgId, intentionDetailDO.getInformedAmount(), intentionDetailDO.getSaleNo(), intentionDetailDO.getMaterialsNo())>0;
                        if(!success){
                            throw new Exception("更新销售意向详情失败");
                        }
                    }
                }
            }
        }
        success = saleIntentionMapper.updateInformStatus(saleIntentionDO.getSaleNo(), "1", orgId) > 0;
        if(!success){
            throw new Exception("更新销售意向失败");
        }
        return true;
    }

    public boolean updateSaleOutStatus(DeliveryNoteDO deliveryNoteDO, String orgId)throws Exception{
        if(deliveryNoteDO == null){
            return false;
        }
        SaleIntentionDO intentionDO = saleIntentionMapper.itemByNo(deliveryNoteDO.getSaleNo(), orgId);
        if(intentionDO == null){
            return false;
        }
        intentionDO.setInventoryOutStatus("1");
        return saleIntentionMapper.update(intentionDO)>0;
    }

    /**
     * @Author: WangKe
     * @Description: 销售冲销入库时更新销售意向单
     * @Date: 2018/3/15 0015
     */
    public boolean updateBySaleReverse(DeliveryNoteDO deliveryNoteDO, String orgId)throws Exception{
        if(deliveryNoteDO == null){
            return false;
        }
        SaleIntentionDO intentionDO = saleIntentionMapper.itemByNo(deliveryNoteDO.getSaleNo(), orgId);
        if(intentionDO == null){
            return false;
        }
        //获取发货详情
        List<DeliveryNoteDetailDO> noteDetailDOList = deliveryNoteDetailMapper.list(deliveryNoteDO.getId());
        if(ListUtil.isNullOrEmpty(noteDetailDOList)){
            return false;
        }
        //将销售意向单的零件编码放到list中
        List<String> materialNoList = new ArrayList<>();
        List<SaleIntentionDetailDO> intentionDetailDOList = saleIntentionDetailMapper.list(intentionDO.getId());
        if(ListUtil.isNullOrEmpty(intentionDetailDOList)){
            return false;
        }
        for(SaleIntentionDetailDO intentionDetailDO : intentionDetailDOList){
            materialNoList.add(intentionDetailDO.getMaterialsNo());
        }
        //更新销售意向单详情中涉及到的零件
        boolean success;
        String deliveryStatus = "0";
        String inventeryStatus = "0";
        for(DeliveryNoteDetailDO noteDetailDO : noteDetailDOList){
            SaleIntentionDetailDO intentionDetailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(intentionDO.getId(), noteDetailDO.getMaterialsNo());
            if(intentionDetailDO == null){
                return false;
            }
            //过滤出未被涉及到的零件
            if(materialNoList.contains(noteDetailDO.getMaterialsNo())){
                materialNoList.remove(noteDetailDO.getMaterialsNo());
            }
            intentionDetailDO.setInformedAmount(intentionDetailDO.getInformedAmount().subtract(noteDetailDO.getDeliveryQty()));
            intentionDetailDO.setInventoryOutAmount(intentionDetailDO.getInventoryOutAmount().subtract(noteDetailDO.getInventoryOutAmount()));
            if(intentionDetailDO.getInformedAmount().compareTo(BigDecimal.ZERO) <= 0){
                intentionDetailDO.setInformedAmount(new BigDecimal(0));
            }else{
                deliveryStatus = "1";
            }
            if(intentionDetailDO.getInventoryOutAmount().compareTo(BigDecimal.ZERO) <= 0){
                intentionDetailDO.setInventoryOutAmount(new BigDecimal(0));
                intentionDetailDO.setInventoryOutStatus("0");
            }else{
                intentionDetailDO.setInventoryOutStatus("1");
                inventeryStatus = "1";
            }
            success = saleIntentionDetailMapper.update(intentionDetailDO)>0;
            if(!success){
                return false;
            }
            deliveryNoteDetailMapper.updateSendQty(orgId, intentionDetailDO.getInformedAmount(),
                    intentionDO.getSaleNo(), intentionDetailDO.getMaterialsNo());
        }
        if("0".equals(deliveryStatus) && !ListUtil.isNullOrEmpty(materialNoList)){
            for(String materialNo : materialNoList){
                SaleIntentionDetailDO intentionDetailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(intentionDO.getId(), materialNo);
                if(intentionDetailDO == null){
                    return false;
                }
                if(intentionDetailDO.getInformedAmount().compareTo(BigDecimal.ZERO) > 0){
                    deliveryStatus = "1";
                    break;
                }
            }
        }
        if("0".equals(inventeryStatus) && !ListUtil.isNullOrEmpty(materialNoList)){
            for(String materialNo : materialNoList){
                SaleIntentionDetailDO intentionDetailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(intentionDO.getId(), materialNo);
                if(intentionDetailDO == null){
                    return false;
                }
                if(intentionDetailDO.getInventoryOutAmount().compareTo(BigDecimal.ZERO) > 0){
                    inventeryStatus = "1";
                    break;
                }
            }
        }
        intentionDO.setDeliverStatus(deliveryStatus);
        intentionDO.setInventoryOutStatus(inventeryStatus);
        success = saleIntentionMapper.update(intentionDO)>0;
        return success;
    }
//    /**
//     * @Author: gyj  todo
//     * @Description: 获取零件实时价格（存在未知参数）
//     * @Date: 2018/4/11
//     */
//    public BigDecimal getSapPrice(String materialsNo,String orgId) {
//        List<MaterialsVO> materialsVOList=new ArrayList<>();
//        CompanyInfoVO companyInfoVO=companyInfoService.info(orgId);
//        if(companyInfoVO==null){
//            LogHelper.error("获取sap零件价格时企业不存在",ErrorCode.RequestIdError.getCode());
//            return null;
//        }
//        ImportParam importParam = new ImportParam();
//        importParam.setFunction("ZPMS_BJ_GET_PRICE");
//        Map<String, String> commonParamMap = new HashMap<>();
//        commonParamMap.put("VKORG", companyInfoVO.getSapCode());
//        //分销渠道VTWEG
//        //com monParamMap.put("VTWEG", companyInfoVO.getSapCode());
//        //价格组
//        //commonParamMap.put("KONDA", companyInfoVO.getSapCode());
//        commonParamMap.put("MATNR",materialsNo);
//        importParam.setCommonParamMap(commonParamMap);
//        importParam.setSapCode(companyInfoVO.getSapCode());
//        LogHelper.monitor("========调用获取零件实时价格接口开始========");
//        OutputParam outputParam = SAPCommonUtil.getData(importParam);
//        LogHelper.monitor("========调用获取零件实时价格接口结束========");
//        if(outputParam==null){
//            LogHelper.error("sap返回值为null",ErrorCode.RequestIdError.getCode());
//            return null;
//        }
//        return new BigDecimal(outputParam.getDataHeader().get("KBETR_ZPR4"));
//
//    }

    /**
     * 调整销售意向
     * @param saleAddVO
     * @param orgId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode adjust(SaleAddVO saleAddVO, String orgId, String userId, String userName) throws  Exception
    {
        SaleIntentionVO saleIntentionVO = saleAddVO.getHeaderInfo();
        List<SaleIntentionDetailVO> detailVOList = saleAddVO.getMaterialList();
        SaleIntentionDO saleIntentionDO=saleIntentionMapper.item(saleIntentionVO.getId());
        if(saleIntentionDO==null){
            return ErrorCode.IllegalArument;
        }
        //String entityId = saleIntentionMapper.selectIdByNo(saleIntentionVO.getSaleNo());
        SaleIntentionDO entity = new SaleIntentionDO();
        entity.setTotalDiscountPrice(new BigDecimal("0"));
        entity.setTotalSettlementPrice(new BigDecimal("0"));
        entity.setId(saleIntentionDO.getId());
        entity.setCashShortAndOver(saleIntentionVO.getCashShortAndOver());
        SaleIntentionDO saleIntention=saleIntentionMapper.item(saleIntentionDO.getId());
        List<SaleIntentionDetailDO> detailDOList = new ArrayList<>();
        List<SaleIntentionDetailDO> detailDOLists=saleIntentionDetailMapper.list(saleIntentionDO.getId());
        BigDecimal adjustTotal=BigDecimal.ZERO;
        BigDecimal deliveryTotal=BigDecimal.ZERO;
        entity.setReceiveAddress(saleAddVO.getHeaderInfo().getReceiveAddress());
        entity.setReceiverName(saleAddVO.getHeaderInfo().getReceiverName());
        entity.setReceiverPhone(saleAddVO.getHeaderInfo().getReceiverPhone());
        if(saleIntentionDO.getReceiveAddress()!=null && !saleIntentionDO.getReceiveAddress().equals(entity.getReceiveAddress())){
            entity.setAddressCode(StringUtils.EMPTY);
        }

        entity.setRemark(saleAddVO.getHeaderInfo().getRemark());

        //处理调整时新增的数据
        addByAdjust(saleIntention, saleAddVO.getBakMaterialsList());

        for (SaleIntentionDetailVO temp : detailVOList)
        {
            SaleIntentionDetailDO saleIntentionDetailDO=new SaleIntentionDetailDO();
            BeanUtils.copyProperties(temp,saleIntentionDetailDO);
            if(detailDOLists.contains(saleIntentionDetailDO)){
                detailDOLists.remove(saleIntentionDetailDO);
            }

            SaleIntentionDetailDO detailDO;
            //如果为1，代表是替换零件
            if (StringUtils.equals("1",temp.getIsReplaceMaterial())) {
                detailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(saleIntentionVO.getId(), temp.getOriginalMaterialsNo());
                detailDO.setOriginalMaterialsNo(temp.getOriginalMaterialsNo());
                detailDO.setMaterialsNo(temp.getMaterialsNo());
                detailDO.setMaterialsDes(temp.getMaterialsDes());
                detailDO.setUnit(temp.getUnit());
                detailDO.setIsReplaceMaterial("1");
                detailDO.setPrice(temp.getPrice().multiply(new BigDecimal(100)));
                detailDO.setApplyTotalPrice(temp.getApplyTotalPrice().multiply(new BigDecimal(100)));
            }else{
                detailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(saleIntentionVO.getId(), temp.getMaterialsNo());
            }

            adjustTotal=adjustTotal.add(detailDO.getAmountAfterAdjust());
            deliveryTotal=deliveryTotal.add(detailDO.getInformedAmount());
            if(detailDO.getInventoryOutAmount().compareTo(temp.getAmountAfterAdjust())>0)
            {
               return ErrorCode.AdjustMountTooLess;
            }
            if("2".equals(detailDO.getInventoryOutStatus())){
                continue;
            }
            if(detailDO.getInformedAmount().compareTo(temp.getAmountAfterAdjust())>0)
            {
                return ErrorCode.AdjustMountError;
            }
            if(detailDO.getReturnApplyAmount()!=null && detailDO.getReturnApplyAmount().compareTo(temp.getAmountAfterAdjust())>0)
            {
                return ErrorCode.AdjustMountReturnError;
            }

            detailDO.setPriceSchemeId(temp.getPriceSchemeId());
            detailDO.setPriceSchemeName(temp.getPriceSchemeName());
            detailDO.setAmountAfterAdjust(temp.getAmountAfterAdjust()); //  调整后数量
            detailDO.setUnitPriceAfterAdjust(rounding(temp.getUnitPriceAfterAdjust()));//调整后单价
            detailDO.setTotalPriceAfterAdjust(detailDO.getUnitPriceAfterAdjust().multiply(temp.getAmountAfterAdjust()));//调整后总价(折后价)
            detailDO.setIsRaise(temp.getIsRaise());
            //detailDO.setApplyTotalPrice(detailDO.getPrice().multiply(temp.getAmountAfterAdjust()));
            entity.setTotalSettlementPrice(entity.getTotalSettlementPrice().add(detailDO.getApplyTotalPrice()));
            entity.setTotalDiscountPrice(entity.getTotalDiscountPrice().add(detailDO.getTotalPriceAfterAdjust()));
            detailDOList.add(detailDO);
            adjustTotal=adjustTotal.add(detailDO.getAmountAfterAdjust());
            deliveryTotal=deliveryTotal.add(detailDO.getInformedAmount());
        }
        if(!CollectionUtils.isEmpty(detailDOLists)){
            for(SaleIntentionDetailDO sidDO:detailDOLists){
                if(sidDO.getInformedAmount().compareTo(new BigDecimal(0))!=0){
                    return ErrorCode.AdjustCannotDelete;
                }
                SaleIntentionDetailVO saleIntentionDetail=new SaleIntentionDetailVO();
                BeanUtils.copyProperties(sidDO,saleIntentionDetail);
                saleIntentionDetail.setDeleteReason(saleAddVO.getDeleteReason());
                saleIntentionDeleteReasonService.deleteReason(saleIntentionDetail,orgId,userId,userName);
                if(saleIntentionDetailMapper.itemRemove(sidDO.getId())<=0){
                    return ErrorCode.AdjustDeleteError;
                }
            }
        }

        List<PurchaseRequestDetailDO> purchaseRequestDetailDOS = new ArrayList<>();
        for (SaleIntentionDetailDO detailDO : detailDOList)
        {
            saleIntentionDetailMapper.update(detailDO);

            returnApplyDetailMapper.updateQty(detailDO.getAmountAfterAdjust(), saleIntentionVO.getSaleNo(), detailDO.getMaterialsNo(), saleIntentionVO.getSupplierOrgId());
            if (StringUtils.equals("1",detailDO.getIsReplaceMaterial())) {
                //更新当前销售订单对应采购订单和销售订单明细数据
                // 根据销售订单查找采购订单是否存在
                String purchaseNo = saleIntentionDO.getPurchaseNo();
                if (StringUtils.isNotBlank(purchaseNo)) {
                    PurchaseRequestVO purchaseRequestVO = purchaseRequestService.itemByNo(purchaseNo, null, orgId);
                    BigDecimal totalValue = BigDecimal.ZERO;
                    for (PurchaseRequestDetailVO requestDetailVO : purchaseRequestVO.getMaterialsList()) {
                        if (StringUtils.equals(requestDetailVO.getMaterialsNo(),detailDO.getOriginalMaterialsNo())) {
                            PurchaseRequestDetailDO requestDetailDO = new PurchaseRequestDetailDO();
                            requestDetailDO.setBillId(requestDetailVO.getBillId());
                            requestDetailDO.setOriginalMaterialsNo(requestDetailVO.getMaterialsNo());
                            requestDetailDO.setMaterialsNo(detailDO.getMaterialsNo());
                            requestDetailDO.setMaterialsDes(detailDO.getMaterialsDes());
                            requestDetailDO.setUnit(detailDO.getUnit());
                            requestDetailDO.setPrice(detailDO.getPrice());
                            requestDetailDO.setPriceSchemeId(detailDO.getPriceSchemeId());
                            requestDetailDO.setPriceSchemeName(detailDO.getPriceSchemeName());
                            requestDetailDO.setSettlementPrice(detailDO.getUnitPriceAfterAdjust());
                            BigDecimal applyTotalPrice = requestDetailDO.getSettlementPrice().multiply(requestDetailVO.getQty());
                            requestDetailDO.setApplyTotalPrice(applyTotalPrice);
                            purchaseRequestDetailMapper.updateByOriginalMaterial(requestDetailDO);
                            totalValue = totalValue.add(requestDetailDO.getSettlementPrice().multiply(requestDetailVO.getQty()));

                            //查找上游对应的销售订单是否存在
                            //更新上游的销售订单
                            //根据采购订单查找销售订单
                            String purchaseContractNo = purchaseRequestVO.getPurchaseContractNo();
                            if (StringUtils.isNotBlank(purchaseContractNo)) {
                                SaleIntentionDO itemBySaleIntentionDO = saleIntentionMapper.itemBySaleNo(purchaseContractNo);
                                if (itemBySaleIntentionDO != null) {
                                    //获取销售订单明细
                                    List<SaleIntentionDetailDO> saleIntentionDetailDOS = saleIntentionDetailMapper.list(itemBySaleIntentionDO.getId());
                                    for (SaleIntentionDetailDO saleIntentionDetailDO : saleIntentionDetailDOS) {
                                        if (StringUtils.equals(saleIntentionDetailDO.getMaterialsNo(), detailDO.getOriginalMaterialsNo())) {
                                            saleIntentionDetailDO.setOriginalMaterialsNo(detailDO.getOriginalMaterialsNo());
                                            saleIntentionDetailDO.setMaterialsNo(detailDO.getMaterialsNo());
                                            saleIntentionDetailDO.setMaterialsDes(detailDO.getMaterialsDes());
                                            saleIntentionDetailDO.setPrice(detailDO.getPrice());
                                            saleIntentionDetailDO.setUnit(detailDO.getUnit());
                                            saleIntentionDetailDO.setApplyTotalPrice(detailDO.getApplyTotalPrice());
                                            saleIntentionDetailDO.setUnitPriceAfterAdjust(detailDO.getUnitPriceAfterAdjust());
                                            saleIntentionDetailDO.setTotalPriceAfterAdjust(detailDO.getUnitPriceAfterAdjust()
                                                    .multiply(saleIntentionDetailDO.getAmountAfterAdjust()));
                                            saleIntentionDetailMapper.update(saleIntentionDetailDO);
                                        }
                                    }

                                    //计算销售订单总金额
                                    BigDecimal totalPrice = BigDecimal.ZERO;
                                    BigDecimal discountPrice = BigDecimal.ZERO;
                                    for (SaleIntentionDetailDO saleIntentionDetailDO : saleIntentionDetailDOS) {
                                        totalPrice = totalPrice.add(saleIntentionDetailDO.getPrice().multiply(saleIntentionDetailDO.getQty()));
                                        discountPrice = discountPrice.add(saleIntentionDetailDO.getUnitPriceAfterAdjust().multiply(saleIntentionDetailDO.getQty()));
                                    }
                                    itemBySaleIntentionDO.setTotalSettlementPrice(totalPrice);
                                    itemBySaleIntentionDO.setTotalDiscountPrice(discountPrice);
                                    saleIntentionMapper.update(itemBySaleIntentionDO);
                                }
                            }

                        }else{
                            totalValue = totalValue.add(requestDetailVO.getSettlementPrice().multiply(new BigDecimal(100)).multiply(requestDetailVO.getQty()));
                        }

                    }
                    PurchaseRequestDO purchaseRequestDO = new PurchaseRequestDO();
                    purchaseRequestDO.setTotalValue(totalValue);
                    purchaseRequestDO.setBillId(purchaseRequestVO.getBillId());
                    purchaseRequestMapper.update(purchaseRequestDO);

                }

            }
        }


        if(adjustTotal.compareTo(deliveryTotal)>0){
            entity.setDeliverStatus("1");
        }else if(adjustTotal.compareTo(deliveryTotal)==0)
        {
            entity.setDeliverStatus("2");
        }
        if(deliveryTotal.equals(BigDecimal.ZERO)){
            entity.setDeliverStatus("0");
        }
        if(saleIntention.getPurchaseLevelId()==null || !"1".equals(saleIntention.getPurchaseLevelId())) {
            //判断客户额度是否足够
            ///SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(entity.getId());
            if (saleIntentionDO == null) {
                throw new Exception("未找到主记录");
            }
            CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(saleIntentionDO.getSupplierOrgId(), saleIntentionDO.getPurchaseOrgId());
            if (dealerDO == null) {
                throw new Exception("未找到客户记录");
            }
            if (dealerDO.getEnableLimit() == 1 || saleIntentionDO.getIsLimit() == 1) {
                BigDecimal oldPrice = BigDecimal.ZERO;
                if (saleIntentionDO.getTotalDiscountPrice() != null) {
                    oldPrice = saleIntentionDO.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                }
                BigDecimal newPrice = BigDecimal.ZERO;
                if (entity.getTotalDiscountPrice() != null) {
                    newPrice = entity.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                }
                BigDecimal totalPrice;
                if (saleIntentionDO.getIsLimit() == 0) {
                    totalPrice = dealerDO.getUsedLimit().add(newPrice);
                } else {
                    totalPrice = dealerDO.getUsedLimit().subtract(oldPrice).add(newPrice);
                }
                if (totalPrice.compareTo(dealerDO.getTotalLimit()) > 0) {
                    throw new Exception("客户额度已超额");
                } else {
                    dealerDO.setUsedLimit(totalPrice);
                    companyDealerMapper.update(dealerDO);
                    entity.setIsLimit(1);
                }
            }
        }

        saleIntentionMapper.update(entity);

        //更新发货通知单价格，已过账不更新
        List<String> idsList = deliveryNoteMapper.findIdsForAdjust(saleIntention.getSaleNo(), saleIntention.getSupplierOrgId());
        if(!ListUtil.isNullOrEmpty(idsList)){
            deliveryNoteDetailMapper.updatePriceByAdjust(saleIntention.getId());
            for(String id : idsList){
                deliveryNoteDetailMapper.updateTotalDiscountPriceByAdjust(id);
            }
        }
        return ErrorCode.Success;
    }

    private void addByAdjust(SaleIntentionDO entity, List<SaleIntentionDetailVO> bakMaterialList)throws Exception{
        if (CollectionUtils.isEmpty(bakMaterialList)) {
            return;
        }
        for (SaleIntentionDetailVO detailVO : bakMaterialList) {
            SaleIntentionDetailDO detailDO = new SaleIntentionDetailDO();
            BeanUtils.copyProperties(detailVO, detailDO);
            ActionResult<String> detailDOId = fastGenClient.textGuid();
            if (detailDOId == null || detailDOId.getCode() != 0) {
                throw new Exception("获取主键错误");
            }
            detailDO.setId(detailDOId.getValue());
            detailDO.setSaleIntentionId(entity.getId());
            detailDO.setSaleNo(entity.getSaleNo());
            getDetailDO(null, detailDO);

            if (detailDO.getUnitPriceAfterAdjust() == null) {
                detailDO.setUnitPriceAfterAdjust(BigDecimal.ZERO);
                detailDO.setTotalPriceAfterAdjust(BigDecimal.ZERO);
            }

            if (detailDO.getUnitPriceAfterAdjust() == null || detailDO.getUnitPriceAfterAdjust().compareTo(BigDecimal.ZERO) == 0) {
                entity.setIsSynPrice(1);
            }

            if (!StringUtil.isNullOrEmpty(detailDO.getPriceSchemeId())) {
                MarketingActivityDO marketingActivityDO = marketingActivityMapper.item(detailDO.getPriceSchemeId());
                if (marketingActivityDO == null && !StringUtil.isNullOrEmpty(detailDO.getPriceSchemeName())) {
                    marketingActivityDO = marketingActivityMapper.findByName(entity.getSupplierOrgId(), detailDO.getPriceSchemeName());
                }
                if (marketingActivityDO == null) {
                    throw new Exception("价格策略不存在");
                }
                if (marketingActivityDO.getState().equals(0)) {
                    throw new Exception("价格策略未启用");
                }
            }

            saleIntentionDetailMapper.insert(detailDO);
            entity.setTotalSettlementPrice(entity.getTotalSettlementPrice().add(detailDO.getApplyTotalPrice()));
            entity.setTotalDiscountPrice(entity.getTotalDiscountPrice().add(detailDO.getTotalPriceAfterAdjust()));
        }

        if (entity.getPurchaseLevelId() == null || !"1".equals(entity.getPurchaseLevelId())) {
            //判断客户额度是否足够
            CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(entity.getSupplierOrgId(), entity.getPurchaseOrgId());
            if (dealerDO == null) {
                throw new Exception("未找到客户记录");
            }
            if (dealerDO.getEnableLimit() == 1) {
                BigDecimal price = BigDecimal.ZERO;
                if (entity.getTotalDiscountPrice() != null) {
                    price = entity.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                }
                BigDecimal totalPrice = dealerDO.getUsedLimit().add(price);
                if (totalPrice.compareTo(dealerDO.getTotalLimit()) > 0) {
                    throw new Exception("客户额度已超额");
                } else {
                    dealerDO.setUsedLimit(totalPrice);
                    companyDealerMapper.update(dealerDO);
                    entity.setIsLimit(1);
                }
            }
        }
        if (StringUtils.equals(entity.getDeliverStatus(), "2")) {
            entity.setDeliverStatus("1");
        }
        saleIntentionMapper.update(entity);
    }

    /**
     * 查询销售意向单用于生产采购计划<br>
     *     出库状态：未出库、出库中；<br>
     *     退货状态：未退货；<br>
     *     单据状态：已提交<br>
     *
     * @return  List<SaleIntentionDO>
     */
    public List<SaleIntentionDO> selectAllForPlan()
    {
        List<SaleIntentionDO> saleIntentionDOList = new ArrayList<>();


//        saleIntentionMapper.selectAllForPlan();


        return null;
    }

    /**
     *获取收货人信息
     *
     * @param purchaseOrgId 工厂
     * @param supplierOrgId 当前登录企业
     * @param receiverName 收货人
     * @return
     */
    public List<SaleIntentionVO> listReceivers(String purchaseOrgId, String supplierOrgId, String receiverName) {
        List<SaleIntentionDO>  doList = saleIntentionMapper.listByReceiverName(purchaseOrgId,supplierOrgId, receiverName);
        if (CollectionUtils.isEmpty(doList)) {
            return null;
        }
        List<SaleIntentionVO> voList = new ArrayList<>();
        for (SaleIntentionDO entity : doList) {
            SaleIntentionVO saleIntentionVO = new SaleIntentionVO();
            BeanUtils.copyProperties(entity, saleIntentionVO);
            voList.add(saleIntentionVO);
        }
        return voList;
    }

    /**
     * 意向单满足1.出库状态：未出库、出库中；2.退货状态：未退货；3.单据状态：已提交 所对应的公司ID
     *
     * @return
     */
    public List<String> listOrgIds() {
        return saleIntentionMapper.listOrgIds();
    }

    /**
     * @Author: WangKe
     * @Description: 同步销售意向单详情中没有价格的零件
     * @Date: 2018/7/23 0023
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode synPrice(String id)throws Exception{
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(id);
        if(saleIntentionDO == null){
            return ErrorCode.IllegalArument;
        }

        String purchaseOrgId = saleIntentionDO.getPurchaseOrgId();
        String supplierOrgId = saleIntentionDO.getSupplierOrgId();
        List<SaleIntentionDetailDO> listDO = saleIntentionDetailMapper.listNoPrice(id);
        if(ListUtil.isNullOrEmpty(listDO)){
            throw new Exception("没有需要同步价格的零件");
        }
        //获取发货通知单列表
        DeliveryNoteVO model = new DeliveryNoteVO();
        model.setSupplierOrgId(supplierOrgId);
        model.setSaleNo(saleIntentionDO.getSaleNo());
        List<DeliveryNoteDO> deliveryNoteDOList = deliveryNoteMapper.list(model);

        //同步进出口采购订单、销售订单
        Integer jckFlag = 0;
        Map<String, List<MarketingActivityPriceVO>> priceVOMap = new HashMap<>();
        CompanyDealerDO companyDealerDO = companyDealerMapper.itemByOrgId(supplierOrgId, purchaseOrgId);
        if(companyDealerDO != null && StringUtils.isNotEmpty(companyDealerDO.getPlatOrgId())){
            //判断是否进出口
            CompanyInfoDO companyInfoDO = companyInfoMapper.item(companyDealerDO.getPlatOrgId());
            if (companyInfoDO != null
                    && StringUtils.isNotEmpty(companyInfoDO.getSapCode())
                    && CompanyUtil.JCK_SAP_CODE.equals(companyInfoDO.getSapCode())){
                jckFlag = 1;

                List<String> materialsNos = listDO.stream().map(SaleIntentionDetailDO::getMaterialsNo).distinct().collect(Collectors.toList());
                materialsNos = CollectionUtils.isEmpty(materialsNos) ? Lists.newArrayList("-1") : materialsNos;
                List<MarketingActivityPriceVO> priceVOList = marketingActivityService.activityPrice4Batch(purchaseOrgId, supplierOrgId, materialsNos);
                if (CollectionUtils.isNotEmpty(priceVOList)){
                    priceVOMap = priceVOList.stream().collect(Collectors.groupingBy(MarketingActivityPriceVO::getMaterialsNo));
                }
            }
        }

        boolean success;
        Integer isSynPrice = 0;
        for(SaleIntentionDetailDO detailDO : listDO){
            MarketingActivityPriceVO marInfo = null;
            if (jckFlag == 0){//非进出口
                marInfo = marketingActivityService.activityPriceModel(purchaseOrgId, supplierOrgId, detailDO.getMaterialsNo());
            } else {//进出口查询价格方案列表取第一个
                if (priceVOMap.containsKey(detailDO.getMaterialsNo())){
                    List<MarketingActivityPriceVO> priceVOList = priceVOMap.get(detailDO.getMaterialsNo());
                    if (CollectionUtils.isNotEmpty(priceVOList)){
                        marInfo = priceVOList.get(0);
                    }
                }
            }
            if(marInfo == null){
                isSynPrice = 1;
                continue;
            }
            detailDO.setUnitPriceAfterAdjust(marInfo.getDiscountPrice().multiply(BigDecimal.valueOf(100)));
            detailDO.setTotalPriceAfterAdjust(detailDO.getUnitPriceAfterAdjust().multiply(detailDO.getAmountAfterAdjust()));
            detailDO.setPriceSchemeId(marInfo.getActivityId());
            detailDO.setPriceSchemeName(marInfo.getName());

            success = saleIntentionDetailMapper.update(detailDO) > 0;
            if(!success){
                throw new Exception("更新出错");
            }
            saleIntentionDO.setTotalDiscountPrice(saleIntentionDO.getTotalDiscountPrice().add(detailDO.getTotalPriceAfterAdjust()));

            //更新发货通知单零件价格
            if(!ListUtil.isNullOrEmpty(deliveryNoteDOList)){
                for(DeliveryNoteDO deliveryNoteDO : deliveryNoteDOList){
                    DeliveryNoteDetailDO noteDetailDO = deliveryNoteDetailMapper.itemByMaterialsNo(deliveryNoteDO.getId(), detailDO.getMaterialsNo());
                    if(noteDetailDO == null){
                        continue;
                    }
                    noteDetailDO.setUnitPriceAfterAdjust(detailDO.getUnitPriceAfterAdjust());
                    noteDetailDO.setTotalPriceAfterAdjust(noteDetailDO.getUnitPriceAfterAdjust().multiply(noteDetailDO.getDeliveryQty()));
                    success = deliveryNoteDetailMapper.update(noteDetailDO)>0;
                    if(!success){
                        throw new Exception("更新出错");
                    }

                    deliveryNoteDO.setTotalDiscountPrice(deliveryNoteDO.getTotalDiscountPrice().add(noteDetailDO.getTotalPriceAfterAdjust()));
                }

                for(DeliveryNoteDO deliveryNoteDO : deliveryNoteDOList){
                    success = deliveryNoteMapper.update(deliveryNoteDO)>0;
                    if(!success){
                        throw new Exception("更新出错");
                    }
                }
            }

            // TODO: 2021/5/28 同步进出口销售订单、采购订单价格
            if (jckFlag == 1){
                // 根据销售订单查找采购订单是否存在
                String purchaseNo = saleIntentionDO.getPurchaseNo();
                if (StringUtils.isNotBlank(purchaseNo)) {
                    PurchaseRequestVO purchaseRequestVO = purchaseRequestService.itemByNo(purchaseNo, null, purchaseOrgId);
                    BigDecimal totalValue = BigDecimal.ZERO;
                    for (PurchaseRequestDetailVO requestDetailVO : purchaseRequestVO.getMaterialsList()) {
                        if (StringUtils.equals(requestDetailVO.getMaterialsNo(),detailDO.getMaterialsNo())) {
                            PurchaseRequestDetailDO requestDetailDO = new PurchaseRequestDetailDO();
                            requestDetailDO.setBillId(requestDetailVO.getBillId());
                            requestDetailDO.setMaterialsNo(detailDO.getMaterialsNo());
                            requestDetailDO.setPriceSchemeId(detailDO.getPriceSchemeId());
                            requestDetailDO.setPriceSchemeName(detailDO.getPriceSchemeName());
                            requestDetailDO.setSettlementPrice(detailDO.getUnitPriceAfterAdjust());
                            BigDecimal applyTotalPrice = requestDetailDO.getSettlementPrice().multiply(requestDetailVO.getQty());
                            requestDetailDO.setApplyTotalPrice(applyTotalPrice);
                            purchaseRequestDetailMapper.update(requestDetailDO);
                            totalValue = totalValue.add(requestDetailDO.getSettlementPrice().multiply(requestDetailVO.getQty()));

                            //查找上游对应的销售订单是否存在
                            //更新上游的销售订单
                            //根据采购订单查找销售订单
                            String purchaseContractNo = purchaseRequestVO.getPurchaseContractNo();
                            if (StringUtils.isNotBlank(purchaseContractNo)) {
                                SaleIntentionDO itemBySaleIntentionDO = saleIntentionMapper.itemBySaleNo(purchaseContractNo);
                                if (itemBySaleIntentionDO != null) {
                                    //获取销售订单明细
                                    List<SaleIntentionDetailDO> saleIntentionDetailDOS = saleIntentionDetailMapper.list(itemBySaleIntentionDO.getId());
                                    //计算销售订单总金额
                                    BigDecimal discountPrice = BigDecimal.ZERO;
                                    for (SaleIntentionDetailDO saleIntentionDetailDO : saleIntentionDetailDOS) {
                                        if (StringUtils.equals(saleIntentionDetailDO.getMaterialsNo(), detailDO.getMaterialsNo())) {
                                            saleIntentionDetailDO.setUnitPriceAfterAdjust(detailDO.getUnitPriceAfterAdjust());
                                            saleIntentionDetailDO.setTotalPriceAfterAdjust(detailDO.getUnitPriceAfterAdjust()
                                                    .multiply(saleIntentionDetailDO.getAmountAfterAdjust()));
                                            saleIntentionDetailDO.setPriceSchemeId(detailDO.getPriceSchemeId());
                                            saleIntentionDetailDO.setPriceSchemeName(detailDO.getPriceSchemeName());
                                            saleIntentionDetailMapper.update(saleIntentionDetailDO);
                                        }
                                        discountPrice = discountPrice.add(saleIntentionDetailDO.getTotalPriceAfterAdjust());
                                    }
                                    itemBySaleIntentionDO.setTotalDiscountPrice(discountPrice);
                                    saleIntentionMapper.update(itemBySaleIntentionDO);
                                }
                            }

                        }else{
                            totalValue = totalValue.add(requestDetailVO.getSettlementPrice().multiply(new BigDecimal(100)).multiply(requestDetailVO.getQty()));
                        }

                    }
                    PurchaseRequestDO purchaseRequestDO = new PurchaseRequestDO();
                    purchaseRequestDO.setTotalValue(totalValue);
                    purchaseRequestDO.setBillId(purchaseRequestVO.getBillId());
                    purchaseRequestMapper.update(purchaseRequestDO);
                }
            }

        }
        saleIntentionDO.setIsSynPrice(isSynPrice);
        success = saleIntentionMapper.update(saleIntentionDO) > 0;
        if(!success){
            throw new Exception("更新出错");
        }
        return ErrorCode.Success;

    }

    public ErrorCode importAttach(String billId, MultipartFile file) throws Exception{
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(billId);
        if(saleIntentionDO == null){
            return ErrorCode.IllegalArument;
        }
        if("2".equals(saleIntentionDO.getDeliverStatus())){
            return ErrorCode.IllegalArument;
        }
        String fileName = billId + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        FileUtil.uploadFile(file,filePath+"purchase_request_attach/", fileName);
        SaleIntentionDO temp = new SaleIntentionDO();
        temp.setId(billId);
        temp.setAttachName(fileName);
        return saleIntentionMapper.update(temp)>0?ErrorCode.Success:ErrorCode.Failure;
    }

    public void downloadAttach(String billId) throws Exception{
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(billId);
        if(saleIntentionDO == null || StringUtil.isNullOrEmpty(saleIntentionDO.getAttachName())){
            return;
        }
        FileUtil.downLoadFile(response,filePath+"purchase_request_attach/",saleIntentionDO.getAttachName());
    }

    /**
     * 根据主表主键获取行数量
     *
     * @param saleIntentionId
     * @return
     */
    public int getDetailQty(String saleIntentionId) {
        return saleIntentionDetailMapper.countBySaleIntentionId(saleIntentionId);
    }

    /**
     * 修改订单售后状态，目前铲运电商调用（2019-05-28）
     *
     * @param afterSaleStatus
     * @param saleNo
     */
    public void updateAfterSaleStatus(Integer afterSaleStatus, String saleNo, String sapCode) throws Exception {
        CompanyInfoDO companyInfoDO = companyInfoMapper.itemBySap(sapCode);
        if (null == companyInfoDO) {
            throw  new Exception("无此sapCode");
        }

        SaleIntentionDO saleIntentionDO = saleIntentionMapper.itemByNo(saleNo, companyInfoDO.getOrgId());
        if (null == saleIntentionDO) {
            throw  new Exception("未查询到此订单信息");
        }
        saleIntentionMapper.updateAfterSaleStatus(afterSaleStatus, saleNo);
    }

    /**
     * 是否审核：0否1是
     */
    private static final Integer CHECK_FLAG_YES = 1;

    /**
     * 基础审核
     * @param id
     * @param checkFlag
     * @param userId
     */
    public void audit4JC(String id, Integer checkFlag, String userId) throws Exception {
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(id);
        if (null == saleIntentionDO) {
            throw new Exception("单据不存在");
        }
        if (CHECK_FLAG_YES.equals(saleIntentionDO.getCheckFlag())) {
            throw new Exception("单据状态为审核通过，请不要重复审核");
        }
        if (String.valueOf(SaleStatus.Submit.getCode()).equals(saleIntentionDO.getStatus())) {
            throw new Exception("单据已提交，不能审核");
        }
        saleIntentionDO.setCheckFlag(checkFlag);
        saleIntentionDO.setUpdateDate(new Date());
        saleIntentionDO.setUpdatorId(userId);
        saleIntentionMapper.update(saleIntentionDO);
    }

    @Transactional(rollbackFor = Exception.class)
    public FunctionResult importLackInfo(InputStream in, String orgId, String userId) throws Exception {
        FunctionResult result = new FunctionResult();
        HSSFWorkbook wb = new HSSFWorkbook(in);
        HSSFSheet sheet = wb.getSheetAt(0);

        int totalRow = sheet.getLastRowNum();
        if (totalRow < 2) {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("模板错误");
            return result;
        }
        int totalCell = sheet.getRow(2).getLastCellNum();
        if (totalCell != 6) {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("模板错误");
            return result;
        }

        SaleIntentionDetailVO intentionDetailVO;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
        for (int i = 2; i <= totalRow; i++) {
            HSSFRow curRow = sheet.getRow(i);
            if (curRow == null) {
                continue;
            }
            String saleNo = getCellValue(curRow, 1);
            String materialsNo = getCellValue(curRow, 2);

            String deliveryDate = getCellValue(curRow, 4);
            String deliveryDesc = getCellValue(curRow, 5);

            if (StringUtils.isBlank(saleNo) || StringUtils.isBlank(materialsNo)) {
                result.setCode(ErrorCode.IllegalArument);
                result.setValue("第" + (i+1) + "行，销售单号或零件号不能为空");
                return result;
            }

            if (StringUtils.isBlank(deliveryDate) && StringUtils.isBlank(deliveryDesc)) {
                result.setCode(ErrorCode.IllegalArument);
                result.setValue("第" + (i+1) + "行，交付时间和交付说明不能同时为空");
                return result;
            }
            SaleIntentionDO saleIntentionDO = saleIntentionMapper.itemByNo(saleNo, orgId);
            if(saleIntentionDO == null){
                result.setCode(ErrorCode.IllegalArument);
                result.setValue("第" + (i+1) + "行，订单"+ saleNo +"不存在");
                return result;
            }
            SaleIntentionDetailDO intentionDetailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(saleIntentionDO.getId(), materialsNo);
            if(intentionDetailDO == null){
                result.setCode(ErrorCode.IllegalArument);
                result.setValue("第" + (i+1) + "行，零件"+ materialsNo +"不存在");
                return result;
            }
            if (StringUtils.isNotBlank(deliveryDate)) {
                intentionDetailDO.setDeliveryDate(dateFormat.parse(deliveryDate));
                intentionDetailDO.setDeliveryCreateDate(new Date());
                intentionDetailDO.setDeliveryCreateId(userId);
                intentionDetailDO.setDeliveryCreateName(commonService.getUserName(userId));
            }
            if (StringUtils.isNotBlank(deliveryDesc)) {
                intentionDetailDO.setLackRemark(deliveryDesc);
                intentionDetailDO.setLackCreateId(userId);
            }
            saleIntentionDetailMapper.update(intentionDetailDO);
        }
        result.setCode(ErrorCode.Success);
        result.setValue(ErrorCode.Success.getDesc());
        return result;
    }

    private String getCellValue(HSSFRow curRow, int indexNo) {
        if (null == curRow.getCell(indexNo)) {
            return StringUtils.EMPTY;
        }
        return curRow.getCell(indexNo).getStringCellValue();
    }

    public void updateLackInfo(SaleIntentionDetailVO intentionDetailVO, String orgId, String userId){
        if (null == intentionDetailVO.getDeliveryDate() && StringUtils.isBlank(intentionDetailVO.getLackRemark())) {
            return;
        }
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.itemByNo(intentionDetailVO.getSaleNo(), orgId);
        if(saleIntentionDO == null){
            return;
        }
        SaleIntentionDetailDO intentionDetailDO = saleIntentionDetailMapper.findBySaleIntentionIdAndMaterialsNo(saleIntentionDO.getId(), intentionDetailVO.getMaterialsNo());
        if(intentionDetailDO == null){
            return;
        }
        if (null != intentionDetailVO.getDeliveryDate()) {
            intentionDetailDO.setDeliveryDate(intentionDetailVO.getDeliveryDate());
            intentionDetailDO.setDeliveryCreateDate(new Date());
            intentionDetailDO.setDeliveryCreateId(userId);
            intentionDetailDO.setDeliveryCreateName(commonService.getUserName(userId));
        }
        if (StringUtils.isNotBlank(intentionDetailVO.getLackRemark())) {
            intentionDetailDO.setLackRemark(intentionDetailVO.getLackRemark());
            intentionDetailDO.setLackCreateId(userId);
        }
        saleIntentionDetailMapper.update(intentionDetailDO);
    }

    /**
     * 下载缺货报表导入模板
     *
     * @throws Exception
     */
    public void downloadLackTemplate() throws Exception{
        FileUtil.downLoadFile(response, filePath, LACK_TEMPLATE_NAME);
    }

    /**
     * 根据crmOrder查询记录
     * @param crmOrder
     * @return
     */
    public List<SaleIntentionDO> getSaleIntentionByCrmOrder(String crmOrder){
        if(StringUtils.isEmpty(crmOrder)){
            return null;
        }
        List<SaleIntentionDO> saleIntentions = saleIntentionMapper.findByCrmOrder(crmOrder);
        if(CollectionUtils.isEmpty(saleIntentions)){
            return null;
        }
        return saleIntentions;
    }

    public List<SaleIntentionDetailVO> item4JckDelivery(String saleId){
        List<SaleIntentionDetailDO> listDO = saleIntentionDetailMapper.listWithRownum(saleId);
        if (CollectionUtils.isEmpty(listDO)){
            return null;
        }
        List<SaleIntentionDetailDO> sortListDO = listDO.stream().sorted(Comparator.comparing(SaleIntentionDetailDO::getMaterialsNo)).collect(Collectors.toList());
        return BeanUtil.do2bo4List(sortListDO,SaleIntentionDetailVO.class);

    }


    public FunctionResult importReplaceExcel(String saleId, InputStream in, String dealerOrgId, String orgId, String targetOrgId) throws Exception
    {
        //判断谁是采购方和供方,进出口特殊需判断
        String purchaseOrgId = dealerOrgId;
        String supplierOrgId  = orgId;
        if (StringUtils.isNotEmpty(targetOrgId)){//供应商
            purchaseOrgId = orgId;
            supplierOrgId = targetOrgId;
        }
        FunctionResult result = new FunctionResult();
        HSSFWorkbook wb = new HSSFWorkbook(in);
        HSSFSheet sheet = wb.getSheetAt(0);

        int totalRow = sheet.getLastRowNum();
        if (totalRow < 3)
        {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        int totalCell = sheet.getRow(2).getLastCellNum();
        if (totalCell != 3)
        {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        //获取销售订单
        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(saleId);
        List<DeliveryNoteDetailDO> deliveryNoteDetailDOS = deliveryNoteDetailMapper.listBySaleNo(saleIntentionDO.getSaleNo());

        //获取订单明细
        List<SaleIntentionDetailDO> saleIntentionDetailDOS = saleIntentionDetailMapper.list(saleId);

        List<SaleIntentionDetailVO> detailVOList = new ArrayList<>();

        for (SaleIntentionDetailDO saleIntentionDetailDO : saleIntentionDetailDOS) {
            SaleIntentionDetailVO saleIntentionDetailVO = new SaleIntentionDetailVO();
            BeanUtils.copyProperties(saleIntentionDetailDO, saleIntentionDetailVO);
            if (saleIntentionDetailVO.getPrice() != null) {
                saleIntentionDetailVO.setPrice(saleIntentionDetailVO.getPrice().divide(new BigDecimal(100)));
            }
            if (saleIntentionDetailVO.getUnitPriceAfterAdjust() != null) {
                saleIntentionDetailVO.setUnitPriceAfterAdjust(saleIntentionDetailVO.getUnitPriceAfterAdjust().divide(new BigDecimal(100)));
            }
            if (saleIntentionDetailVO.getApplyTotalPrice() != null) {
                saleIntentionDetailVO.setApplyTotalPrice(saleIntentionDetailVO.getApplyTotalPrice().divide(new BigDecimal(100)));
            }
            if (saleIntentionDetailVO.getTotalPriceAfterAdjust() != null) {
                saleIntentionDetailVO.setTotalPriceAfterAdjust(saleIntentionDetailVO.getTotalPriceAfterAdjust().divide(new BigDecimal(100)));
            }
            List <MarketingActivityPriceVO> MarketingActivityDOList=marketingActivityService.activityPriceList(purchaseOrgId, supplierOrgId, saleIntentionDetailVO.getMaterialsNo());
            saleIntentionDetailVO.setMarketingActivityPriceVOList(MarketingActivityDOList);
            detailVOList.add(saleIntentionDetailVO);
        }

        //销售订单零件集合
        List<String> materialsNos = detailVOList.stream().map(SaleIntentionDetailVO::getMaterialsNo).distinct().collect(Collectors.toList());

        List<SaleIntentionDetailVO> errorDetailVOList = new ArrayList<>();
        for (int i = 3; i <= totalRow; i++)
        {
            HSSFRow curRow = sheet.getRow(i);
            SaleIntentionDetailVO detailVO = new SaleIntentionDetailVO();
            if (curRow == null)
            {
                continue;
            }
            if(isRowEmpty(curRow)){
                continue;
            }
            String oldMaterialsNo = excelValue(curRow,1);
            String newMaterialsNo = excelValue(curRow, 2);
            MaterialsVO oldMaterialsVO = materialsService.itemByNo(oldMaterialsNo, orgId);
            if (oldMaterialsVO == null) {
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark(oldMaterialsNo + "原零件信息不存在");
                errorDetailVOList.add(detailVO);
                continue;
            }

            MaterialsVO newMaterialsVO = materialsService.itemByNo(newMaterialsNo, orgId);
            if (newMaterialsVO == null) {
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark(newMaterialsNo + "新零件信息不存在");
                errorDetailVOList.add(detailVO);
                continue;
            }

            //替换零件在原零件中存在，不允许替换
            if (materialsNos.contains(newMaterialsNo)){
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark("新零件号【"+ newMaterialsNo +"】在销售单中已存在，不允许替换");
                errorDetailVOList.add(detailVO);
                continue;
            }

            //校验原始零件是否已创建发货通知单
            if (deliveryNoteDetailDOS != null) {
                long count = deliveryNoteDetailDOS.stream().filter(item -> StringUtils.equals(item.getMaterialsNo(), oldMaterialsNo)).count();
                if (count > 0) {
                    result.setCode(ErrorCode.Failure);
                    result.setValue("零件" + oldMaterialsNo + "已创建发货通知单，不允许编辑");
                    return result;
                }
            }

            boolean flag = false;
            for (SaleIntentionDetailVO saleIntentionDetailDO : detailVOList) {
                if (StringUtils.equals(saleIntentionDetailDO.getMaterialsNo(), oldMaterialsNo)) {
                    flag = true;
                    saleIntentionDetailDO.setOriginalMaterialsNo(saleIntentionDetailDO.getMaterialsNo());
                    saleIntentionDetailDO.setMaterialsNo(newMaterialsVO.getMaterialsNo());
                    saleIntentionDetailDO.setMaterialsDes(newMaterialsVO.getMaterialsDes());
                    saleIntentionDetailDO.setIsReplaceMaterial("1");
                    saleIntentionDetailDO.setUnitPriceAfterAdjust(newMaterialsVO.getPrice());
                    BigDecimal newPrice = newMaterialsVO.getPrice();
                    if (newPrice == null) {
                        newPrice = BigDecimal.ZERO;
                    }
                    saleIntentionDetailDO.setPrice(newPrice);
                    saleIntentionDetailDO.setUnit(newMaterialsVO.getUnit());
                    saleIntentionDetailDO.setIsMinimumBuy(newMaterialsVO.getIsMinimumBuy());
                    saleIntentionDetailDO.setMinimumBuy(newMaterialsVO.getMinimumBuy());
                    MarketingActivityPriceVO marInfo=marketingActivityService.activityPriceModel(purchaseOrgId, supplierOrgId, saleIntentionDetailDO.getMaterialsNo());
                    saleIntentionDetailDO.setSettlementPrice(saleIntentionDetailDO.getUnitPriceAfterAdjust()==null?newMaterialsVO.getPrice():saleIntentionDetailDO.getUnitPriceAfterAdjust());
                    if(marInfo != null){
                        saleIntentionDetailDO.setSettlementPrice(saleIntentionDetailDO.getUnitPriceAfterAdjust()==null?marInfo.getDiscountPrice():saleIntentionDetailDO.getUnitPriceAfterAdjust());
                        saleIntentionDetailDO.setPriceSchemeId(marInfo.getActivityId());
                        saleIntentionDetailDO.setPriceSchemeName(marInfo.getName());
                    }

                    if (StringUtils.isNotBlank(saleIntentionDetailDO.getPriceSchemeId())) {
                        BigDecimal targetPrice = purchaseRequestService.calculatePrice(saleIntentionDetailDO.getPriceSchemeId(), saleIntentionDetailDO.getPrice(), dealerOrgId, orgId, saleIntentionDetailDO.getMaterialsNo(),null);
                        saleIntentionDetailDO.setSettlementPrice(targetPrice);
                    }
                    saleIntentionDetailDO.setApplyTotalPrice(saleIntentionDetailDO.getSettlementPrice().multiply(saleIntentionDetailDO.getQty()));
                    saleIntentionDetailDO.setUnitPriceAfterAdjust(saleIntentionDetailDO.getSettlementPrice()==null?BigDecimal.ZERO:saleIntentionDetailDO.getSettlementPrice());
                    saleIntentionDetailDO.setTotalPriceAfterAdjust(saleIntentionDetailDO.getUnitPriceAfterAdjust().multiply(saleIntentionDetailDO.getQty()));
                    List <MarketingActivityPriceVO> MarketingActivityDOList=marketingActivityService.activityPriceList(purchaseOrgId, supplierOrgId, saleIntentionDetailDO.getMaterialsNo());
                    saleIntentionDetailDO.setMarketingActivityPriceVOList(MarketingActivityDOList);
                    EnableAndOccupyVO enableAndOccupyVO = warehouseInventoryService.findEnableAndOccupyNum(saleIntentionDetailDO.getMaterialsNo(), supplierOrgId, null);
                    if(enableAndOccupyVO!=null){
                        saleIntentionDetailDO.setIntentionNum(enableAndOccupyVO.getIntentionNum());
                        saleIntentionDetailDO.setDeliveryNum(enableAndOccupyVO.getDeliveryNum());
                        saleIntentionDetailDO.setEnableNum(enableAndOccupyVO.getEnableNum());
                    }
                }
            }

            if (!flag) {
                result.setCode(ErrorCode.Failure);
                result.setValue(oldMaterialsNo + "原零件在单据中不存在");
                return result;
            }
        }

        if (ListUtil.isNullOrEmpty(errorDetailVOList)) {
            //零件合并
//            result.setValue(materialsReplaceDeRepeat(detailVOList));
            result.setValue(detailVOList);
            result.setCode(ErrorCode.Success);
        } else {
            result.setValue(errorDetailVOList);
            result.setCode(ErrorCode.IllegalArument);
        }
        return result;
    }

//    /**
//    * @Desc   同步销售意向到NS
//    * @Author Mr.dong
//    * @Date   2021/3/31 14:35
//    */
//    @Transactional(rollbackFor = Exception.class)
//    public ErrorCode synSaleIntention4NS(String id) throws Exception{
//        SaleIntentionDO saleIntentionDO = saleIntentionMapper.item(id);
//        if(saleIntentionDO == null){
//            return ErrorCode.IllegalArument;
//        }
//        if(saleIntentionDO.getCreateType() == 0){
//            throw new Exception("采购申请创建销售订单不能同步");
//        }
//
//        if(saleIntentionDO.getSyncNsStatus() == 1){
//            throw new Exception("销售订单已同步NS系统，请勿重复同步");
//        }
//
//        String orgId = saleIntentionDO.getSupplierOrgId();
//        List<PushSaleIntentionReq> intentionReqList = Lists.newArrayList();
//        PushSaleIntentionReq intentionReq = new PushSaleIntentionReq();
//        //查询供应商编号
//        CompanySupplierDO companySupplierDO = companySupplierMapper.itemBySupplierOrgId(orgId, saleIntentionDO.getTargetOrgId());
//
//        if (null == companySupplierDO){
//            throw new Exception("销售订单供应商不存在，请联系管理员");
//        }
//        if (StringUtils.isEmpty(companySupplierDO.getSupplierCode())){
//            throw new Exception("销售订单供应商编号不能为空");
//        }
//        if (StringUtils.isEmpty(companySupplierDO.getCompanyName())){
//            throw new Exception("销售订单供应商名称不能为空");
//        }
//        intentionReq.setVendorNum(companySupplierDO.getSupplierCode());
//        intentionReq.setVendorName(companySupplierDO.getCompanyName());
//        intentionReq.setPoNum(saleIntentionDO.getSaleNo());
//        intentionReq.setOrderDate(ToolTime.getStringBySlash(saleIntentionDO.getCreateDate()));
//        //查询国家简称
//        ServiceBasicDataAgentVO dataAgentVO = new ServiceBasicDataAgentVO();
//        dataAgentVO.setOrgId(orgId);
//        dataAgentVO.setpCode("country");
//        dataAgentVO.setName(saleIntentionDO.getCountry());
//        List<ServiceBasicDataAgentDO> agentDOS = serviceBasicDataAgentMapper.queryList(dataAgentVO);
//        if (CollectionUtils.isEmpty(agentDOS) || StringUtils.isEmpty(agentDOS.get(0).getCode())){
//            throw new Exception("销售订单国家简称不能为空");
//        }
//        intentionReq.setCountry(agentDOS.get(0).getCode());
//        intentionReq.setShipMethod(saleIntentionDO.getDeliverTypeName());
//
//        //查询创建人及部门编号
//        Map<String,ProfileDTO> profileDTOMap = new HashMap<>();
//
//        List<String> userIds = Lists.newArrayList(saleIntentionDO.getCreatorId());
//        ActionResult<List<ProfileDTO>>  profileResult = authClient.listByIds(userIds.toArray(new String[userIds.size()]));
//        if(ErrorCode.Success.getCode() != profileResult.getCode()) {
//            throw new Exception(profileResult.getMessage());
//        }
//        List<ProfileDTO> profileList = profileResult.getValue();
//        if (CollectionUtils.isEmpty(profileList)){
//            throw new Exception("创建人及部门编号不能为空");
//        }
//        intentionReq.setDepartment(profileList.get(0).getDeptId());//业务部门
//        intentionReq.setCreatedBy(profileList.get(0).getSapCode());//创建人
//        intentionReq.setCurrency("CNY");
//        intentionReqList.add(intentionReq);
//        String jsonPayload = JSONArray.toJSON(intentionReqList).toString();
//        LogHelper.monitor("========同步Ns数据内容============"+jsonPayload+"====================");
//        String result = NsTokenAuth.callWithHttpPost(saleIntentionUrl, consumerKey, consumerSecret,
//                tokenId, tokenSecret, realm, jsonPayload).getBody();
//        Map map = JSONArray.parseObject(result);
//        if (null != map){
//            if (null != map.get("success") && (boolean)map.get("success")){
//                saleIntentionDO.setSyncNsStatus(1);
//                boolean success = saleIntentionMapper.update(saleIntentionDO)>0;
//                if(!success){
//                    throw new Exception("更新销售订单同步NS状态失败");
//                }
//            }else{
//                throw new Exception((String)map.get("message"));
//            }
//        }else{
//            throw new Exception("销售订单同步NS失败");
//        }
//
//
//        return ErrorCode.Success;
//
//    }
}
